Here’s some helpful functions for Arduino.
Blinking an LED
This function blinks an LED light as many times as requested, at the requested blinking rate.
void blinkLED(byte targetPin, int numBlinks, int blinkRate) { for (int i=0; i < numBlinks; i++) { digitalWrite(targetPin, HIGH); delay(blinkRate); digitalWrite(targetPin, LOW); delay(blinkRate); } }
Blinking a Number
Back in the dawn age of computing sometimes things went wrong enough that the only way to communicate an error to the user was to blink a light. When dealing with micro-controllers this can sometimes come in handy. The following function blinks a sequence to indicate a number visually.
void blinkNumber(char* numString) { int versLength = strlen(numString); delay(200); for (int i =0 ; i < versLength; i++) { int number = numString[i] -48; if (number == 0){ blinkLED(LED_A,1,20); delay(160); } if (number > 0 && number < 10) blinkLED(LED_A,number,200); delay(400); } }
Buzzing a Buzzer
A generalised generalised function to make use of Piezo buzzers without having to think through the math each time you want to hear a particular sound frequency. All you need to do is tell the function which pin you’d like to use, the frequency you want to hear, and the duration to play that frequency.
void buzz(int targetPin, long frequency, long length) { long delayValue = 1000000/frequency/2; long numCycles = frequency * length/ 1000; for (long i=0; i < numCycles; i++){ digitalWrite(targetPin,HIGH); delayMicroseconds(delayValue); digitalWrite(targetPin,LOW); delayMicroseconds(delayValue); } }
Checking Free RAM
The ATmega328 has 32K of program memory but only 2K of SRAM. Program memory is for code and RAM is for dynamic variables. Actually it’s effectively less than 2K of RAM, because the Arduino libraries will take up some dynamic memory space for themselves.
The Arduino environment will happily let you compile a program that exceeds the micro-controller’s SRAM limits, however program behavior will become totally unpredictable, the code will do bizarre things and/or crash. This function will return the number of bytes currently free in SRAM.
int memoryTest() { int byteCounter = 0; byte *byteArray; while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) { byteCounter++; free(byteArray); } free(byteArray); return byteCounter; }
Mapping Bigger Numbers
This is a version of the map function capable of handling larger positive numbers, although it fails with negative ones.
long mapBig(unsigned long x, unsigned long in_min, unsigned long in_max, unsigned long out_min, unsigned long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }
Connecting to WiFi
The new Arduino WiFi shield is a pretty nice board. However dealing with different types of network can be troublesome. The following code snippet, will attempt to connect to a WPA/WPA2 encrypted WiFi network whose SSID is stored in the ssid variable, and password stored in the pass variable. However if it can’t find that network it will fall back and scan for open WiFi networks instead.
if (WiFi.status() == WL_NO_SHIELD) { Serial.println("WiFi shield not present"); while(true); } if ( stringFromCharString(ssid) != "" ) { while ( status != WL_CONNECTED) { timesWeTriedToConnect++; Serial.print(F("Attempting to connect to SSID (attempt ")); Serial.print( timesWeTriedToConnect ); Serial.print(F(" of 5): ")); Serial.println(ssid); status = WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. delay(2000); if ( timesWeTriedToConnect >= 5 ) break; } } if ( status != WL_CONNECTED ) { Serial.print("Unable to connect to ssid '"); Serial.print( ssid ); Serial.println( "'"); Serial.println("** Scanning for open networks **"); byte numSsid = WiFi.scanNetworks(); Serial.print("number of available networks:"); Serial.println(numSsid); for (int thisNet = 0; thisNet<numSsid; thisNet++) { Serial.print(thisNet); Serial.print(") "); Serial.print(WiFi.SSID(thisNet)); Serial.print("tSignal: "); Serial.print(WiFi.RSSI(thisNet)); Serial.print(" dBm"); Serial.print("tEncryption: "); Serial.println(WiFi.encryptionType(thisNet)); if ( WiFi.encryptionType(thisNet) == 7 ) { Serial.println( "Attempting to connect to open network..."); status = WiFi.begin( WiFi.SSID(thisNet)); delay(10000); if( status == WL_CONNECTED ) break; } } } if ( status != WL_CONNECTED ) { Serial.println( "Unable to connect to network" ); // don't continue: while(true); }
Reading and Writing to the EEPROM
Sometimes it can be useful to store numbers, or other data, into the Arduino’s EEPROM to protect it against power-cycling. Using the included EEPROM library it’s actually pretty easy to write a number to EEPROM,
void setNumber(unsigned long ctr) { Serial.print("Setting number in EEPROM to = "); Serial.println( ctr ); EEPROM.write(4,(ctr & 0xFFFFFFFF) >> 24); // write the MSB EEPROM.write(3,(ctr & 0xFFFFFF) >> 16); // write the 3rdB EEPROM.write(2,(ctr & 0xFFFF) >> 8); // write the 2ndB EEPROM.write(1,ctr & 0xFF); // write the LSB }
and then to read the number back,
unsigned long getNumber() { unsigned long ctr; //initial setting of number if (EEPROM.read(5) != 1) { // if number set status is false Serial.println("Initializing number in EEPROM"); EEPROM.write(1,0); // write LSB zero EEPROM.write(2,0); // write 2ndB zero EEPROM.write(3,0); // write 3rdB zero EEPROM.write(4,0); // write MSB zero EEPROM.write(5,1); // counter set status is true } //get the number - add Bytes for 32-bit number ctr = (EEPROM.read(4) << 24) + (EEPROM.read(3) << 16) + (EEPROM.read(2) << 8) + (EEPROM.read(1)); Serial.print("Getting number from EEPROM = "); Serial.println( ctr ); return ctr; }
Code for this post was provided by Rob Faludi and Alasdair Allan. It is reposted here on the MAKE site with permission.
ADVERTISEMENT