last updated: 2020-12-21
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.
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);
}
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);
}
// 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]);
}
}
}
// 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;
}
}
// 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;
}
}