Microcontroller projects

Arduino code snippets

last updated: 2020-12-21

Introduction

First I thought I could make a library with my custom functions, an this library would solve all my problems :).

But then I noticed it made programs often less clear. For most programs that are not too big I like to use the Arduino IDE because simplicity is important for beginners and students (and me :)). So I decided to document here code snippet that I use quite often.

Code snippets

LED helper functions

I think these are quite self-explaining. It is possible to change the logic, as some BUILTIN LED's use negative logic.

    // cs_led_helper_functions.ino
    // weigu.lu

    const byte LED_PIN = LED_BUILTIN;   // LED_BUILTIN or other pin
    bool LED_LOGIC = 1;                 // positive logic: 1, negative logic: 0
    const unsigned long DELAY_MS = 3000;
    const unsigned long LED_BLINK_DELAY_MS = 100;

    void setup() {
      init_led();
    }

    void loop() {
      blink_led_x_times(3,LED_BLINK_DELAY_MS);
      delay(DELAY_MS);
    }

    /****** LED HELPER functions *************************************************/

    // initialise the build in LED and switch it on
    void init_led() {
      pinMode(LED_PIN,OUTPUT);
      led_on();
    }

    // LED on
    void led_on() {
      LED_LOGIC ? digitalWrite(LED_PIN,HIGH) : digitalWrite(LED_PIN,LOW);
    }

    // LED off
    void led_off() {
      LED_LOGIC ? digitalWrite(LED_PIN,LOW) : digitalWrite(LED_PIN,HIGH);
    }

    // blink LED x times (LED was on) with delay_time_ms
    void blink_led_x_times(byte x, word delay_time_ms) {
      for(byte i = 0; i < x; i++) { // Blink x times
        led_off();
        delay(delay_time_ms);
        led_on();
        delay(delay_time_ms);
      }
    }
    // toggle LED
    void toggle_led(byte pin) {
      digitalRead(pin) ? digitalWrite(pin, LOW) : digitalWrite(pin, HIGH);
    }

Non blocking delay

With the millis()-function we can create a non blocking delay. With the following function it gets simpler by using a static variable in the function:

    // cs_non_blocking_delay.ino
    // weigu.lu 

    const byte LED_PIN = LED_BUILTIN;   // LED_BUILTIN or other pin
    bool LED_LOGIC = 1;                 // positive logic: 1, negative logic: 0
    const unsigned long NON_BLOCKING_DELAY_MS = 3000;
    const unsigned long LED_BLINK_DELAY_MS = 100;

    void setup() {
      init_led();
    }

    void loop() {
      if (non_blocking_delay(NON_BLOCKING_DELAY_MS)) {
        blink_led_x_times(3,LED_BLINK_DELAY_MS);
      }
      // do here whatever you want :)
    }

    // non blocking delay using millis(), returns true if time is up
    bool non_blocking_delay(unsigned long milliseconds) {
      static unsigned long nb_delay_prev_time = 0;
      if(millis() >= nb_delay_prev_time + milliseconds) {
        nb_delay_prev_time += milliseconds;
        return true;
      }
      return false;
    }

    /****** LED HELPER functions *************************************************/
    ...

Sometimes we need more delays. So we quit the returning bool variable and return the case within a byte:

    // cs_non_blocking_delay_x3.ino
    // weigu.lu 

    const byte PIN_LED2 = 2;// non blocking delay using millis(), returns true if time is up
    const byte PIN_LED3 = 3;

    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
      pinMode(PIN_LED2, OUTPUT);
      pinMode(PIN_LED3, OUTPUT);
    }

    void loop() {
      switch (non_blocking_delay_x3(100, 200, 400)) {
        case 1:
          toggle_led(LED_BUILTIN);  
          break;
        case 2:
          toggle_led(PIN_LED2);  
          break;
        case 3:
          toggle_led(PIN_LED3);  
          break;
        case 0:  
          break;
      }
      // do whatever you want here
    }

    byte non_blocking_delay_x3(unsigned long ms_1, unsigned long ms_2,
                               unsigned long ms_3) {
      static unsigned long nb_delay_prev_time_1 = 0;
      static unsigned long nb_delay_prev_time_2 = 0;
      static unsigned long nb_delay_prev_time_3 = 0;
      unsigned long millis_now = millis();
      if(millis_now >= nb_delay_prev_time_1 + ms_1) {
        nb_delay_prev_time_1 += ms_1;
        return 1;    
      }
      if(millis_now >= nb_delay_prev_time_2 + ms_2) {
        nb_delay_prev_time_2 += ms_2;
        return 2;
      }
      if(millis_now >= nb_delay_prev_time_3 + ms_3) {
        nb_delay_prev_time_3 += ms_3;
        return 3;
      }  
      return 0;  
    }

    // toggle LED
    void toggle_led(byte pin) {
      digitalRead(pin) ? digitalWrite(pin, LOW) : digitalWrite(pin, HIGH);
    }

Convert a C-string with hex bytes to real bytes

    // cs_convert_cstring_w_bytes_2_bytes.ino
    // convert a C-string with hex bytes to real bytes
    // weigu.lu

    char c_string[] = "53414767700067C800000782";      // the c_string

    void setup() {
      Serial.begin(115200);
      delay(2500);
      Serial.println("Serial ok");
      Serial.print("The c_string: \"");
      Serial.print(c_string);
      byte byte_array_size = strlen(c_string)/2;
      byte byte_array[byte_array_size];                // the byte array with half the size
      c_string_hexbytes_2_bytes(c_string, byte_array); // array passed by ref
      Serial.print("\"\nThe byte array in hex: ");
      for (int i=0; i<12; i++) {
        Serial.print(byte_array[i],HEX);
        Serial.print(" ");
      }
    }

    void loop() {
    }

    // convert a C-string with hex bytes to real bytes
    void c_string_hexbytes_2_bytes(char c_string[], byte byte_array[]) {
      byte tmp_array_size = strlen(c_string);
      byte tmp_array[tmp_array_size];
      for (byte i=0; i<tmp_array_size; i++) {
        if ((c_string[i]>='A') && (c_string[i]<='F')) tmp_array[i] = byte(c_string[i]-55);
        else if ((c_string[i]>='a') && (c_string[i]<='f')) tmp_array[i] = byte(c_string[i]-87);
        else if ((c_string[i]>='0') && (c_string[i]<='9')) tmp_array[i] = byte(c_string[i]-48);
        else {
          Serial.println("error init IV");
          return -1;
        }
        if (i%2==1) {                                  // i odd (every second character)
          byte_array[(i-1)/2] = byte((tmp_array[i-1]*16)+tmp_array[i]);
        }
      }
    }

Convert a C-string to C-string with hex values

    // cs_convert_cstring_2_hex_cstring.ino
    // convert a C-string to C-string with hex values
    // weigu.lu

    char mytext[] = "BTS-IoT2";

    void setup() {
      Serial.begin(115200);
      delay(1000);
      Serial.println("Monitor alive\n");
      char hex_text[strlen(mytext)*2];  // C-string with double length
      cstring_2_hex_cstring(mytext, hex_text);
      Serial.print("\"");
      Serial.print(mytext);
      Serial.print("\" gives us the following Hex C-string: \"");
      Serial.print(hex_text);
      Serial.println("\"");
    }

    void loop() {
    }

    // convert a C-string to C-string with hex values
    void cstring_2_hex_cstring(char text[], char hextext[]) {
      for (byte i=0; i<strlen(text); i++) {
        hextext[i*2] = (text[i] >> 4) & 0x0F; // high nibble    
        hextext[i*2] <= 9 ? hextext[i*2] += 0x30 : hextext[i*2] += 0x37;
        hextext[i*2+1] = text[i] & 0x0F;      // low nibble
        hextext[i*2+1] <= 9 ? hextext[i*2+1] += 0x30 : hextext[i*2+1] += 0x37;
      }
    }

Convert an unsigned long number to C-string with hex values

    // cs_convert_unsigned_long_2_hex_cstring.ino
    // convert an unsigned long number to C-string with hex values
    // weigu.lu

    unsigned long mynumber = 0x12345678; // 4 Byte

    void setup() {
      Serial.begin(115200);
      delay(3000);
      Serial.println("Monitor alive\n");
      char mybuff[8];    
      ulong_2_hex_cstring(mynumber, mybuff);
      Serial.print("The number ");
      Serial.print(mynumber);
      Serial.print(" (0x");
      Serial.print(mynumber,HEX);  
      Serial.print(") gives us the following Hex C-string: \"");
      Serial.print(mybuff);
      Serial.println("\"");
    }

    void loop() {
    }

    // convert an unsigned long number to C-string with hex values
    void ulong_2_hex_cstring(unsigned long number, char hextext[]) {
      byte d;  
      for (short i=3; i>=0; i--) {      
        d = number%256;
        number = number/256;  
        hextext[i*2] = (d >> 4) & 0x0F; // high nibble
        hextext[i*2] <= 9 ? hextext[i*2] += 0x30 : hextext[i*2] += 0x37;
        hextext[i*2+1] = d & 0x0F;      // low nibble
        hextext[i*2+1] <= 9 ? hextext[i*2+1] += 0x30 : hextext[i*2+1] += 0x37;    
      }
    }

Downloads