Microcontroller projects

Arduino code snippets

last updated: 2023-10-29

Quick links

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.

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;    
      }
    }

Get the daylight saving time for Europe (Luxembourg)

We can choose one of two functions. One function needs only the date. The other needs also the day of week, so a third function calculates the day of week from the date.

    // cs_get_daylight_saving_time.ino
    // weigu.lu

    #include <TimeLib.h>

    String dow_str[] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};

    void setup() {  
      Serial.begin(115200);
      setTime(10,0,10,28,10,23); // set UTC: hr,min,sec,day,month,year
      Serial.println("UTC: " + String(year()) + '-' + str_02u(String(month())) + '-' +
              str_02u(String(day())) + 'T' + str_02u(String(hour())) + ':' +
              str_02u(String(minute())) + ':' + str_02u(String(second())));
      int dow = day_of_week(day(),month(),year());
      Serial.print("Day of week: " + dow_str[dow]);
      Serial.print(" Daylight_saving: f1: " + String(is_daylight_saving_time_from_dow(day(),month(),dow)));
      Serial.println(" f2: " + String(is_daylight_saving_time(day(),month(),year())));
      time_t t = now();
      if (is_daylight_saving_time(day(),month(),year())==1) {
        t = t + 7200;
      }
      else {
        t = t + 3600;
      }
      setTime(t);
      Serial.println("Corrected time: " + String(year()) + '-' + str_02u(String(month())) + '-' +
              str_02u(String(day())) + 'T' + str_02u(String(hour())) + ':' +
              str_02u(String(minute())) + ':' + str_02u(String(second())));
    }
    void loop() {
    }

    // add leading zero to string with 1 digit
    String str_02u(String s) {
      if (s.length()==1) {
        s = '0' + s;    
      }
      return s;
    }

    // calculate day of week from date (Zeller’s Congruence method) 
    // 6 = Saturday, 0 = Sunday, 1 = Monday, …, 5 = Friday
    int day_of_week(int d, int m, int y) {  
      int dow = ((d + int(2.6 * (((m + 12 - 3) % 12) + 1) - 0.2) - 40 + 
                (m < 3 ? y-1 : y) + int((m < 3 ? y-1 : y)/4) + 5)-1) % 7;
      return dow;            
    } 

    // for europe needing day of week (1 = monday)
    bool is_daylight_saving_time_from_dow(int d, int m, int dow) {
      int previous_sunday = d - dow;
      if (m < 3 || m > 10)  return false; 
      if (m > 3 && m < 10)  return true; 
      if (m == 3) return previous_sunday >= 25;
      if (m == 10) return previous_sunday < 25;  
    }

    // for europe
    bool is_daylight_saving_time(int d, int m, int y) {    
      byte y2 = y % 100;        
      byte x1 = 31 - (y2 + y2 / 4 - 2) % 7; //last Sunday March
      byte x2 = 31 - (y2 + y2 / 4 + 2) % 7; // last Sunday October
      if ((m > 3 && m < 10) || (m == 3 && d >= x1) || (m == 10 && d < x2)) {
        return 1;
      }  
      else {
        return 0;
      }
    }

Downloads