lkm1638-display-toggle-leds

Sets a text to the display. Uses the buttons on the LKM1638 as toggles. Lights up the corresponding LEDs.
Author: Jan Vantomme
License: BSD
Github: jv/lkm1638/lkm1638 display toggle led.axo

Inlets

None

Outlets

bool32 Toggle 1 Status

bool32 Toggle 2 Status

bool32 Toggle 3 Status

bool32 Toggle 4 Status

bool32 Toggle 5 Status

bool32 Toggle 6 Status

bool32 Toggle 7 Status

bool32 Toggle 8 Status

Attributes

table display

Declaration
uint8_t *txbuf;
uint8_t *rxbuf;

bool btn1;
bool btn2;
bool btn3;
bool btn4;
bool btn5;
bool btn6;
bool btn7;
bool btn8;

bool btn1_on;
bool btn2_on;
bool btn3_on;
bool btn4_on;
bool btn5_on;
bool btn6_on;
bool btn7_on;
bool btn8_on;

uint8_t buttons_prev;

char txt[8];

// Font to use on the display
// ------------------------------------

uint8_t tm1638_font(char c) {
  const uint8_t f[] = {
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x22, 0x7e,
      0x6d, 0x00, 0x00, 0x02, 0x30, 0x06, 0x63, 0x00, 0x04, 0x40, 0x80, 0x52,
      0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x27, 0x7f, 0x6f, 0x00, 0x00,
      0x00, 0x48, 0x00, 0x53, 0x5f, 0x77, 0x7f, 0x39, 0x3f, 0x79, 0x71, 0x3d,
      0x76, 0x06, 0x1f, 0x69, 0x38, 0x15, 0x37, 0x3f, 0x73, 0x67, 0x31, 0x6d,
      0x78, 0x3e, 0x2a, 0x1d, 0x76, 0x6e, 0x5b, 0x39, 0x64, 0x0f, 0x00, 0x08,
      0x20, 0x5f, 0x7c, 0x58, 0x5e, 0x7b, 0x31, 0x6f, 0x74, 0x04, 0x0e, 0x75,
      0x30, 0x55, 0x54, 0x5c, 0x73, 0x67, 0x50, 0x6d, 0x78, 0x1c, 0x2a, 0x1d,
      0x76, 0x6e, 0x47, 0x46, 0x06, 0x70, 0x01, 0x00};

  return (c > 127) ? 0 : f[(unsigned char)c];
}

// Send a raw character to the display
// ------------------------------------

void tm1638_set_7seg_raw(uint8_t digit, uint8_t n) {
  tm1638_send_data(digit << 1, n);
}

// Send a text to the display
// ------------------------------------

void tm1638_set_7seg_text(const char *str, uint8_t dots) {
  const char *p = str;

  for (int i = 0, j = 1; i < 8; i++, j <<= 1) {
    // We want the loop to finish, but don't walk over the end of the string
    char c = *p;
    if (c) {
      p++;
    }

    uint8_t f = tm1638_font(c);

    if (dots & j) {
      f |= 128;
    }

    tm1638_set_7seg_raw(i, f);
  }
}

// Send a command to the TM1638 Chip
// ------------------------------------

void tm1638_send_command(uint8_t x) {
  SPID1.spi->CR1 |= SPI_CR1_BIDIOE;
  spiSelect(&SPID1);
  txbuf[0] = x;
  spiSend(&SPID1, 1, &txbuf[0]);
  spiUnselect(&SPID1);
}

// Send data to the TM1638 Chip
// ------------------------------------

void tm1638_send_data(uint8_t addr, uint8_t data) {
  SPID1.spi->CR1 |= SPI_CR1_BIDIOE;
  tm1638_send_command(0x44);
  txbuf[0] = addr | 0xc0;
  txbuf[1] = data;
  spiSelect(&SPID1);
  spiSend(&SPID1, 2, txbuf);
  spiUnselect(&SPID1);
}

uint8_t tm1638_read_buttons(void) {

  // LogTextMessage("Reading Buttons!");

  txbuf[0] = 0x42;
  txbuf[1] = 0;
  txbuf[2] = 0;
  txbuf[3] = 0;
  txbuf[4] = 0;
  txbuf[5] = 0;
  txbuf[6] = 0;
  txbuf[7] = 0;

  spiSelect(&SPID1);
  spiSend(&SPID1, 1, &txbuf[0]);
  palSetPadMode(GPIOA, 7, PAL_MODE_INPUT); // MOSI -> tristate
  spiReceive(&SPID1, 4, &rxbuf[0]);
  spiUnselect(&SPID1);
  palSetPadMode(GPIOA, 7, PAL_MODE_ALTERNATE(5)); // MOSI -> output

  uint8_t out = 0;

  out += rxbuf[0] & 0x01 ? 1 : 0;
  out += rxbuf[1] & 0x01 ? 2 : 0;
  out += rxbuf[2] & 0x01 ? 4 : 0;
  out += rxbuf[3] & 0x01 ? 8 : 0;
  out += rxbuf[0] & 0x10 ? 16 : 0;
  out += rxbuf[1] & 0x10 ? 32 : 0;
  out += rxbuf[2] & 0x10 ? 64 : 0;
  out += rxbuf[3] & 0x10 ? 128 : 0;

  btn1 = rxbuf[0] & 0x01 ? true : false;
  btn2 = rxbuf[1] & 0x01 ? true : false;
  btn3 = rxbuf[2] & 0x01 ? true : false;
  btn4 = rxbuf[3] & 0x01 ? true : false;
  btn5 = rxbuf[0] & 0x10 ? true : false;
  btn6 = rxbuf[1] & 0x10 ? true : false;
  btn7 = rxbuf[2] & 0x10 ? true : false;
  btn8 = rxbuf[3] & 0x10 ? true : false;

  return out;
}

// Set the color for a single LED
// ------------------------------------
// 0 = OFF
// 1 = GREEN
// 2 = RED

void tm1638_set_led(uint8_t led, uint8_t cols) {
  tm1638_send_data((led << 1) + 1, cols);
}

// SETUP
// ------------------

void setup() {

  static uint8_t _txbuf[8] __attribute__((section(".sram2")));
  static uint8_t _rxbuf[8] __attribute__((section(".sram2")));

  txbuf = _txbuf;
  rxbuf = _rxbuf;

  // Copy the text from the text field into the txt variable
  strcpy(&txt[0], "attr_display");

  // Send the text to the display
  tm1638_set_7seg_text(txt, 0);
}

// LOOP
// ------------------

void loop() {

  chThdSleepMilliseconds(1);

  uint8_t buttons = tm1638_read_buttons();

  // LogTextMessage("Buttons: %i", buttons );
  // LogTextMessage("PREV Buttons: %i", buttons_prev );

  uint8_t buttons_pressed = buttons & ~buttons_prev;

  // LogTextMessage("Buttons Pressed: %i", buttons_pressed );

  if (buttons_pressed) { // or buttons pressed > 0 ???

    if (btn1 == true) {
      btn1_on = !btn1_on;
    }
    if (btn2 == true) {
      btn2_on = !btn2_on;
    }
    if (btn3 == true) {
      btn3_on = !btn3_on;
    }
    if (btn4 == true) {
      btn4_on = !btn4_on;
    }
    if (btn5 == true) {
      btn5_on = !btn5_on;
    }
    if (btn6 == true) {
      btn6_on = !btn6_on;
    }
    if (btn7 == true) {
      btn7_on = !btn7_on;
    }
    if (btn8 == true) {
      btn8_on = !btn8_on;
    }

    if (btn1_on == true) {
      tm1638_set_led(0, 2);
    } else {
      tm1638_set_led(0, 0);
    }

    if (btn2_on == true) {
      tm1638_set_led(1, 2);
    } else {
      tm1638_set_led(1, 0);
    }

    if (btn3_on == true) {
      tm1638_set_led(2, 2);
    } else {
      tm1638_set_led(2, 0);
    }

    if (btn4_on == true) {
      tm1638_set_led(3, 2);
    } else {
      tm1638_set_led(3, 0);
    }

    if (btn5_on == true) {
      tm1638_set_led(4, 2);
    } else {
      tm1638_set_led(4, 0);
    }

    if (btn6_on == true) {
      tm1638_set_led(5, 2);
    } else {
      tm1638_set_led(5, 0);
    }

    if (btn7_on == true) {
      tm1638_set_led(6, 2);
    } else {
      tm1638_set_led(6, 0);
    }

    if (btn8_on == true) {
      tm1638_set_led(7, 2);
    } else {
      tm1638_set_led(7, 0);
    }
  }

  buttons_prev = buttons;
}

// ------------------------------------------------------------------------------------------------
// THREADS
// ------------------------------------------------------------------------------------------------

msg_t ThreadX2() {
  setup();
  while (!chThdShouldTerminate()) {
    loop();
    chThdSleepMilliseconds(1);
  }

  chThdExit((msg_t)0);
}

static msg_t ThreadX(void *arg) { ((attr_parent *)arg)->ThreadX2(); }

WORKING_AREA(waThreadX, 1024);

Thread *Thd;
Init
Thd = chThdCreateStatic(waThreadX, sizeof(waThreadX), NORMALPRIO, ThreadX,
                        (void *)this);

btn1 = false;
btn2 = false;
btn3 = false;
btn4 = false;
btn5 = false;
btn6 = false;
btn7 = false;
btn8 = false;

btn1_on = false;
btn2_on = false;
btn3_on = false;
btn4_on = false;
btn5_on = false;
btn6_on = false;
btn7_on = false;
btn8_on = false;

buttons_prev = 0;
Control Rate
outlet_toggle1 = btn1_on;
outlet_toggle2 = btn2_on;
outlet_toggle3 = btn3_on;
outlet_toggle4 = btn4_on;
outlet_toggle5 = btn5_on;
outlet_toggle6 = btn6_on;
outlet_toggle7 = btn7_on;
outlet_toggle8 = btn8_on;
Dispose
chThdTerminate(Thd);
chThdWait(Thd);

Privacy

© 2024 Zrna Research