Arduino IDE – Tips en tricks
Soft Autoreset met code
Het is mogelijk om een arduino te resetten met de code
1 |
asm volatile (" jmp 0"); |
Een mooi voorbeeld geeft deze code, je ziet dat de “setup” routine telkens weer aangehaald word:
1 2 3 4 5 6 7 8 9 10 |
void setup() { Serial.begin(9600); Serial.println("Hallo Wereld!"); } void loop() { Serial.println("Dit is mijn programma..."); delay(2000); asm volatile (" jmp 0"); } |
1 2 3 4 5 6 7 8 |
Hallo Wereld! Dit is mijn programma... Hallo Wereld! Dit is mijn programma... Hallo Wereld! Dit is mijn programma... Hallo Wereld! Dit is mijn programma... |
Een ander voorbeeld (werkt ook op de ATTiny):
1 2 3 |
void(* resetFunc) (void) = 0; // declare reset function at address 0 ... resetFunc(); // call reset |
Huidige Datum en Tijd (van de computer) compileren in de code
In cd C++ taal van ade arduino kun je de computer tijd en datum gebruiken in de code bij compilatie, bijvoorbeeld handig als je een RTC wilt programmeren:
__TIME__ geeft
13:15:20 (24 uurs notatie)
__DATE__ geeft
Jul 27 2015 (datum is afgekort in 3 letters in het Engels)
Hieronder heb ik een script gemaakt om de variabele van C++ om te zetten naareen Jaar, Maand, Dag, Uur, Minuut en Seconde variabele:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
String compile_datum = __DATE__; String compile_tijd = __TIME__; //Compile TIJD variabelen: String comp_uur_str = compile_tijd.substring(0, 2); String comp_min_str = compile_tijd.substring(3, 5); String comp_sec_str = compile_tijd.substring(6, 8); int comp_uur_int = comp_uur_str.toInt(); int comp_min_int = comp_min_str.toInt(); int comp_sec_int = comp_sec_str.toInt(); //Compile DATUM variabelen: String comp_dag_str = compile_datum.substring(4, 6); String comp_maand_str_naam = compile_datum.substring(0, 3); String comp_maand_str; String comp_jaar_str = compile_datum.substring(7, 11); int comp_dag_int = comp_dag_str.toInt(); int comp_maand_int; int comp_jaar_int = comp_jaar_str.toInt(); void maandgetal() { if (comp_maand_str_naam == "Jan") { comp_maand_str = "01"; } if (comp_maand_str_naam == "Feb") { comp_maand_str = "02"; } if (comp_maand_str_naam == "Mar") { comp_maand_str = "03"; } if (comp_maand_str_naam == "Apr") { comp_maand_str = "04"; } if (comp_maand_str_naam == "May") { comp_maand_str = "05"; } if (comp_maand_str_naam == "Jun") { comp_maand_str = "06"; } if (comp_maand_str_naam == "Jul") { comp_maand_str = "07"; } if (comp_maand_str_naam == "Aug") { comp_maand_str = "08"; } if (comp_maand_str_naam == "Sep") { comp_maand_str = "09"; } if (comp_maand_str_naam == "Oct") { comp_maand_str = "10"; } if (comp_maand_str_naam == "Nov") { comp_maand_str = "11"; } if (comp_maand_str_naam == "Dec") { comp_maand_str = "12"; } comp_maand_int = comp_maand_str.toInt(); } void setup() { maandgetal(); Serial.begin(9600); Serial.print("Compilatie ISO datum en tijd: "); Serial.print(comp_jaar_str + "-" + comp_maand_str + "-" + comp_dag_str + "/"); Serial.println(comp_uur_str + ":" + comp_min_str + ":" + comp_sec_str); } void loop() { delay(1000); } |
1 |
Compilatie ISO datum en tijd: 2015-07-27/11:51:42 |
En substring vinden in een string
Ik kwam deze functie tegen, het is in principe hetzelfde als de functie substring() (standaard arduino IDE), maar deze werkt met chars, de functie geeft een 1 wanneer gevonden, zo is hij eenvoudig toe te passen in een IF loop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Searches for the string sfind in the string str // returns 1 if string found // returns 0 if string not found char StrContains(char *str, char *sfind) { char found = 0; char index = 0; char len; len = strlen(str); if (strlen(sfind) > len) { return 0; } while (index < len) { if (str[index] == sfind[found]) { found++; if (strlen(sfind) == found) { return 1; } } else { found = 0; } index++; } return 0; } |
Toepassing IF loop:
1 2 3 |
if (StrContains(STRING, "WOORD")) { //DOE IETS } |
Ps. bovenstaande is achterhaald, en is hetzelfde als de strstr functie van de Arduino IDE.
1 2 3 |
if (strstr(STRING, "WOORD")) { //DOE IETS } |
Minimale en Maximale waarde grens instellen
Wellicht heb je een waarde dat niet onder of boven een bepaalde grens mag komen, in principe werkt daarvoor onderstaande code:
1 2 |
if (sensorValue > 1015) {sensorValue = 1015;} if (sensorValue < 350) {sensorValue = 350;} |
Maar je kan ook de constrain functie daarvoor gebruiken:
1 |
sensorValue = constrain(sensorValue, 350, 1015); |
Mappen van waarden
Het mappen van waarden, kun je het beste vergelijken al een “overzetverhouding”, handig voor het gebruik bij analoge poorten op de Arduino.
Het volgende stukje code map een getal tussen de 0 en 1023 op de ingang als 0 tot 180 op de uitgang (servo)
1 2 |
int pot = analogRead(potmeter); // Lees waarde van de potmeter. int pos = map(pot, 0, 1023, 0, 180); // Map de sensorwaarde van 0 t/m 180. |
FLOAT splitten in 2 INT’s
1 2 3 4 5 |
float temp = 25.50; // Split float in 2 integers. int tempheel = temp; int tempdecimaal = (temp - tempheel) * 100; |
Strings splitten op gevonden karakter
Hieronder een voorbeeld om een string te splitten op een gevonden karakter (,)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// Define number of pieces const int numberOfPieces = 4; String pieces[numberOfPieces]; void setup() { Serial.begin(9600); // Keep track of current position in array int counter = 0; // Keep track of the last comma so we know where to start the substring int lastIndex = 0; String input = "123,456,abc,def"; for (int i = 0; i < input.length(); i++) { // Loop through each character and check if it's a comma if (input.substring(i, i+1) == ",") { // Grab the piece from the last index up to the current position and store it pieces[counter] = input.substring(lastIndex, i); // Update the last position and add 1, so it starts from the next character lastIndex = i + 1; // Increase the position in the array that we store into counter++; } // If we're at the end of the string (no more commas to stop us) if (i == input.length() - 1) { // Grab the last part of the string from the lastIndex to the end pieces[counter] = input.substring(lastIndex, i+1); } } Serial.println(pieces[0]); Serial.println(pieces[1]); Serial.println(pieces[2]); Serial.println(pieces[3]); } void loop() { } |
Output:
1 2 3 4 |
123 456 abc def |
Strings splitten op gevonden karakter (method 2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
String getValue(String data, char separator, int index) { int found = 0; int strIndex[] = {0, -1}; int maxIndex = data.length()-1; for(int i=0; i<=maxIndex && found<=index; i++){ if(data.charAt(i)==separator || i==maxIndex){ found++; strIndex[0] = strIndex[1]+1; strIndex[1] = (i == maxIndex) ? i+1 : i; } } return found>index ? data.substring(strIndex[0], strIndex[1]) : ""; } |
You can use this function as follows (with “;” as separator):
1 2 3 |
String part01 = getValue(application_command,';',0); String part02 = getValue(application_command,';',1); String part03 = getValue(application_command,';',2); |
String / Chars etc.
Lengte
String lengte:
Serial.println(mijnstring.length());
Char lengte:
Serial.println(strlen(mijnstring));
String naar Int
int a = mystring.toInt()
String naar Char
Manier #1:
const char* mijnchar = mijnstring.c_str()
Manier #2:
1 2 |
char* mijnchar = new char[mijnstring.length()+1]; mijnstring.toCharArray(mijnchar, mijnstring.length()+1); |
of met vaste grootte
1 2 |
char mijnchar [10]; mijnstring.toCharArray(mijnchar, mijnstring.length()+1); |
Int naar String
Kan: String(mijnint)
Of (bij decimalen): mijnfloat.toString();
Float naar string
1 2 3 4 5 |
float sensordata = sensors.getTempCByIndex(0); int tempheel = sensordata; int tempdecimaal = (sensordata - tempheel) * 100; String temp = String(tempheel) + "." + String(tempdecimaal); const char* tempc = temp.c_str(); |
Detect ODD or EVEN
1 2 3 4 5 6 7 8 9 |
int x = somevalue; if (x % 2 == 0) ==> even // this is the most generic way or if (x % 2 != 0) ==> odd // this is the most generic way or if (x & 0x01) ==> odd // bit magic |
Bytes splitsen in nibbles (4-bit)
Let´s say i have the hexadecimal byte as stated below in a array.
DataByte[0] = 0xB5
How do i separate the byte into two parts,
DataParts[0] = 0xB
DataParts[1] = 0x5
1 2 3 4 |
DataByte = 0xB5; int part1 = DataByte >> 4; int part2 = DataByte & 0xf; |
Nibbles combineren tot een byte
Voorbeeld:
mijnhexcode = digitalRead(3) << 4 | digitalRead(4);
output:
0x00 or 0x01 or 0x11
Empty Serial buffer
It is probably worth mentioning that the poorly named Serial.flush() function does not empty the input buffer. It is only relevant when the Arduino is sending data and its purpose is to block the Arduino until all outgoing the data has been sent.
If you need to ensure the Serial input buffer is empty you can do so like this:
1 2 3 |
while (Serial.available() > 0) { Serial.read(); } |
Bron: https://forum.arduino.cc/index.php?topic=396450.0
Delay of 62.5 ns
__asm__("nop\n\t"); // delay 1 cycle (62.5ns @ 16MHz)
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); // delay 5 cycles
Using A6 and A7 on Arduino NANO
Analog pins A0~A5 are normal pins. You can refer to them as pins 14-19 as well, and they can be used normally as digital pins.
Analog pins A6 and A7 are weird. They can *only* be used for analogRead() – there aren’t any registers to write to for them like there are for other pins.
A6 and A7 are only inputs available to the mux in front of the ADC. There is no digital hardware behind the pins.
Since the pull up is part of the digital latch, those two pins dont have pull ups (nor do they work as digital inputs.)
You can actually use A6 and A7 as ‘digital’ pins with a little bit of logic in your code:
1 2 3 4 5 6 7 8 9 10 |
int pinStateA6 = 0; int pinStateA7 = 0; void setup() { } void loop() { pinStateA6 = analogRead(A6) > 100 ? 0 : 1; pinStateA7 = analogRead(A7) > 100 ? 0 : 1; } |
Random numbers
Simple example to seed a random number
1 |
randomSeed(analogRead(0)); |
Better example….reads all analog ports for better random.
1 2 3 4 5 6 7 8 9 |
randomSeed(GenerateRandom()) int GenerateRandom() { long value = 0; for (int a=0; a<8; a++) { value = value + (analogRead(a)); } return value; } |
Even better using RAW and EEPROM:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
#include <avr/eeprom.h> /*============================================================================== Call reseedRandom once in setup to start random on a new sequence. Uses four bytes of EEPROM. ==============================================================================*/ void reseedRandom( uint32_t* address ) { static const uint32_t HappyPrime = 127807 /*937*/; uint32_t raw; unsigned long seed; // Read the previous raw value from EEPROM raw = eeprom_read_dword( address ); // Loop until a seed within the valid range is found do { // Incrementing by a prime (except 2) every possible raw value is visited raw += HappyPrime; // Park-Miller is only 31 bits so ignore the most significant bit seed = raw & 0x7FFFFFFF; } while ( (seed < 1) || (seed > 2147483646) ); // Seed the random number generator with the next value in the sequence srandom( seed ); // Save the new raw value for next time eeprom_write_dword( address, raw ); } inline void reseedRandom( unsigned short address ) { reseedRandom( (uint32_t*)(address) ); } /*============================================================================== So the reseedRandom raw value can be initialized allowing different applications or instances to have different random sequences. Generate initial raw values... https://www.random.org/cgi-bin/randbyte?nbytes=4&format=h https://www.fourmilab.ch/cgi-bin/Hotbits?nbytes=4&fmt=c&npass=1&lpass=8&pwtype=3 ==============================================================================*/ void reseedRandomInit( uint32_t* address, uint32_t value ) { eeprom_write_dword( address, value ); } inline void reseedRandomInit( unsigned short address, uint32_t value ) { reseedRandomInit( (uint32_t*)(address), value ); } uint32_t reseedRandomSeed EEMEM = 0xFFFFFFFF; void setup( void ) { /* // Example that sets the seed to a specific value // Typically only done during debugging // Uses EEMEM to determine the EEPROM address reseedRandomInit( &reseedRandomSeed, 42 ); */ // Example that reseeds the random number generator each time the application starts // Uses EEMEM to determine the EEPROM address // Most common use reseedRandom( &reseedRandomSeed ); /* // Example that sets the seed to a specific value // Typically only done during debugging // EEPROM address 0 (through 3) is used to store the seed reseedRandomInit( (unsigned short) 0, 42 ); */ /* // Example that reseeds the random number generator each time the application starts // EEPROM address 0 (through 3) is used to store the seed reseedRandom( (unsigned short) 0 ); */ } void loop( void ) { } |
Midden van een string (een string tussen 2 strings vinden)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
void setup() { test(); } void loop() { delay(100); } String midString(String str, String start, String finish){ int locStart = str.indexOf(start); if (locStart==-1) return ""; locStart += start.length(); int locFinish = str.indexOf(finish, locStart); if (locFinish==-1) return ""; return str.substring(locStart, locFinish); } void test(){ Serial.begin(115200); String str = "Get a substring of a String. The starting index is inclusive (the corresponding character is included in the substring), but the optional ending index is exclusive"; Serial.print(">"); Serial.print( midString( str, "substring", "String" ) ); Serial.println("<"); Serial.print(">"); Serial.print( midString( str, "substring", "." ) ); Serial.println("<"); Serial.print(">"); Serial.print( midString( str, "corresponding", "inclusive" ) ); Serial.println("<"); Serial.print(">"); Serial.print( midString( str, "object", "inclusive" ) ); Serial.println("<"); } |
Bron(nen):
https://forum.arduino.cc/index.php?topic=468967.0
https://forum.arduino.cc/index.php?topic=66206.msg537783#msg537783
https://stackoverflow.com/questions/40425625/get-string-between-2-strings-with-arduino/44742802