I am now more through the Udemy Arduino Step by Step course, and have a few more takeways:
Cool sensors: the membrane potentiometer and the flex sensor are cool. For pots, they have three pins, so you don’t need a second resistor to create the voltage divider. But the flex sensor only has two pins, and you need to use an additional resistor to create the voltage divider.
Keypads: there is a parallel connection method, which is obvious and uses 8 digital pins, but there is a way of having a 4×4 use just a single analog in pin using a series of resistors to form unique voltage dividers. I knew this already conceptually, but it was useful to see what resister values would actually be useful to get unique values, and the analog readings that would (likely) correspond to each key. It takes a bunch of calibration, so not exactly an easy or repeatable solution.
Accelerometer: ADXL335 is a super cheap, analog accelerometer. Ebay has them for less than $2. Would have been useful for my bag movement alarm project, instead of the MPU-6050.
Storage – EEPROM: Since the Arduino has SRAM that is can use for processing programs but doesn’t stick around when power is lost, and Flash memory can only be written to when flashing the chip (and this can’t be modified by the program) EEPROM is where it is at!
However, EEPROM stores values individually, so if the data you want to store is made up of more than one byte you need to split it up.
For integers, there are two bytes, so to put an integer into the first two available positions in the EEPROM:
int address = 0; //this is an arbitrary address in the 1024 positions in the internal EEPROM. If could be more if in an external EEPROM.
int a = 1234;
Then, to read them out you need to use the bitshift operator to shift the High byte to the left by 8 bits:
int aHigh = EEPROM.read(0);
int aLow = EEPROM.read(1);
int aHighShifted = aHigh << 8;
int retrievedA = aHighShifted + aLow;
Kind of annoying eh? Having to do all that shifting around? Well, there is good news!! The library EEPROMex (for extended) allows you to abstract away all the shifting and enables support for longs, ints, floats and doubles, as well as supports strings and arrays, and has an update function (so you can extend the EEPROM lifespan). However, adding the library has a flash memory cost, as it adds a couple kb to the size of the sketch.
So now, the sketch would look like:
int address = 0; //same as before
int a = 1234; // same as before
So there is no need to split the int into the high and low bytes, and instead you can do it with one command. To retrieve the data:
int retrievedA = EEPROM.readInt(address);
So no need to bitshift!
However, further looking at the EEPROM library indicates that there are already put() , get() and update() functions, which allow for different data types and also to only write if updated (as opposed to writing all the time). Not sure how the EEPROMex library makes those functions better, however, there seem to be other functions that are helpful, specifically setting a maximum number of writes (particularly good for when debugging!) and managing memory (so you know what memory has been unallocated).
The Udemy course also included using external EEPROM chips. A 256k chip should only cost $1.50 and is fairly tiny, so it provides good value if the amount of data does not require an SD card. The instructor took the code that was available on the arudino website for interfacing with an I2C external EEPROM chip and put it in a new library. There is also another library that is designed to work with a broad range of external EEPROM chips.
Storage – SD card: Format the card into FAT16 or FAT32 so the Arduino can read it, using a computer. You need to include the SD.h library (obvs), but there is a new data type that is used with the SD card: File. To open a file to write to, you use:
File datafile = SD.open(“filename.txt”, FILE_WRITE);
Importantly, the SD card library only supports file names that have 8 characters, plus 3 characters for the extension.
You can then write to it like it is a serial connection (e.g. print, println).
datafile.print(“new data string”)
You can then close the file using:
You can also traverse the directories in the SD card. There are “normal” files, such as txt files, but then there are “special files” that are directories. Directories are still files, that contain other files.
To get the root directory, simple declare a file name = SD.open(“/”), eg (you don’t need to call it root)
root = SD.open(“/”);
The full reference for functions in the library that can be applied to either the SD card or a file is located at the SD Card library reference.
Of note, is that the SPI is fixed in hardware, but the chip/slave select pin is not fixed. However, even if the hardware SS pin is not used, it must be left as an output or the SD library won’t work. I have not experimented with using the pin 10 as an output but using it for something else entirely. The only reason you might do this is because you are short on PWM outputs, as pin 10 is PWM enabled but the SS output only needs to be binary.