The ESP32 S2 Mini i s a small development board based on the ESP32-S2FN4R2 chip. The ESP32-S2 Mini by Wemos can be used as an Arduino, which is what this post covers. It can also be programmed in other ways, including with MicroPython, CircuitPython and with the chip manufacturer’s (Espressif) own software development kit.
Capabilities
The board can be used as an Arduino, although as with all different Arduino boards, it will have quirks that will mean some libraries will need special versions. This is the same as different boards within the Arduino family to a degree, and is often due to a mixture of hardware features being on different pins, or software maturity. It is worth pushing through these issues for the benefits the chip brings over a standard Arudino Uno or similar.
Processor Speed – 240MHz (32bit)
3.3V Power and digital outputs, but 5v tolerant digital input pins (you can send it 5V signals without harm)
USB-C Connector
Wifi capable (can be turned off if not needed)
4MB Flash (for programs, and for storing resources such as images, html files or sounds)
2MB of RAM
27 I/O pins
12 Digital I/O pins
18 Analogue Input Pins
2 Proper Analogue Output Pins (not PWM)
27 PWM Capable Pins
27 Pins Serial Capable
Multiple I2C and SPI Busses
Note this specific chip doesn’t support Bluetooth (unlike other related products which sometimes do).
Adding the Board to the Arduino IDE and First Test
Launch the Arduino IDE (I’m using version 1.8.9 on Linux).
Go to Tools>Boards>Board Manager, and type in “ESP32”.
Select and install Version 3.1 (3.1 is the newest at the time of writing – version 3.0.5 didn’t work properly for me) “esp32 by Espressif Systems” (not “Arduino ESP32 Boards”).
If “esp32 by Espressif Systems” doesn’t show up in the list when you search, go to File>Preferences and add the following text to the “Additional Boards Manager URLs” text box. If there is already text in there, you need to add it to the end, after a comma and a space.
The text to add : https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Returning to the Boards Manager as above, you should now be able to see the “esp32 by Espressif Systems” option when you search.
From the Tools>Boards sub menu, pick the option LOLIN S2 MINI.
Open the Blink example from File>Examples>01.Basics>Blink.
Plug in the board using a USB-C cable.
Press and hold the button on the board labelled “0”, and briefly press the “Reset” button, wait another two seconds and then release the “0” button.
Select the board in the Tools>Port menu.
Click the “Upload” arrow.
Once the upload has finished, it might show an error, but regardless, press the “Reset” button on the board. The onboard LED should start blinking.
If you’re on Linux, you may need to set up USB permissions as per the instructions here.
If you have any issues, try a different USB cable. The first one I tried didn’t work properly (some don’t have all of the wires inside them).
A More Interesting Example
The most useful starting point is the provided example found at File>Examples>WiFi>WiFiAccessPoint. This example turns the board into its own WiFi network (separate to the house network). You can use your phone or laptop to connect to this network, and then load one or more web pages served up by a mini web server on the board. I often use this to provide an easy control interface (buttons and feedback). It is also possible to do firmware updates over WiFi, which can be very useful when the controller is buried deep in a machine. Obviously, make sure you use a password on the WiFi to stop other people messing with things.
Upload the WiFiAccessPoint example onto the S2 Mini board. I’m not certain why, but I had to completely power cycle my S2 Mini before the WiFi appeared.
Plug the S2 Mini into a USB port on your computer and open the serial monitor. Using your phone or laptop, connect to the WiFi access point that has the name yourAP. The default password is yourPassword. You should see information appear in the Serial Monitor, including the “host” IP. This is probably 192.168.4.1. Go to this address in your browser by entering http://192.168.4.1 or just click that link if you have this page open on the computer you connected to the S2 Mini with.
You should be presented with a simple webpage that has two lines of text, each with a link in it. The two links turn the LED on the board On or Off. Clicking them causes more activity in the serial monitor.
Update : I’ve realised that changing the pull up resistor to a pull down resistor means that the circuit will react better if the fan 12V is applied before the Arduino power supply is activated. As such, I’ve moved my resistor so that it is now between the gate pin and ground.
Having a bit of spare time, I decided to transfer a load of files from my previous computer (a Mac) to my new computer (Linux). As I had a lot of data from a number of hard disks to move, I decided the best method would be using an external eSATA drive. Thankfully, due to a stalled home build SAS project I started a few years ago, I have a couple to hand. The are branded as SUUNION SUBE3ZW enclosures, the “E” being optional and meaning they support eSATA. Helpfully they come with an internal SATA to eSATA expansion slot adapter and my motherboard has a feature in the BIOS that lets you turn hot swapping on for a SATA port. Without the latter, I’d have needed to power down my computer every time I wanted to switch in a different disk. These SUUNION enclosures have almost no internet presence, but were really cheap about 7 or 8 years ago when I bought them.
SUBE3ZW Enclosure
While transferring data, I noticed in the S.M.A.R.T data for the drive that it was getting quite warm and had reached 50°C. I looked up the temperature ratings for the drive in question (a 1.5TB Seagate Barracuda) and discovered they were rated to a maximum temperature of 50°C… oh dear. It seems that it isn’t great to run some (7200rpm) disks in fan-less enclosures.
Initially I grabbed my home made soldering air filter (120mm computer fan, connected through an inline power switch to a 12v wall-wart) without the filter to cool it down, but since I had time to kill waiting for the file transfers and the fan was quite loud considering my girlfriend was trying to work in the same room, I started looking into adding some speed control.
The Circuit
Parts used:
1x Arduino Pro Mini (anything similar will do, including an UNO – note that devices with different main chips will have different PWM requirements and the code will not work without changes).
1x 2N7000 MOSFET – an excellent all-rounder MOSFET.
1x 1N4007 Diode – massively over-specified, but I have a bag of them and they cost very little. Any similar diode will do (I suspect anything from the 1N400x range is fine).
1x 10k Resistor (0.5W).
Breadboard – the circuit could be built on protoboard for a more permanent solution.
Some wire, suitable for use in breadboard.
Breadboard Layout of Fan Controller
Three things to take care of :
Do not connect the 12V supply to the microcontroller – this will damage it, and potentially any connected computer.
Note the pins on the left of the Arduino are reversed on some clones – my device has the pins in the opposite order to those shown in the drawing above. If your Arduino matches the drawing above and you are using the same USB adapter as I am, your adapter should be face down into the table. If your Arduino and USB adapter are both identical to mine, the adapter should be face up.
Ensure the USB adapter power jumper is set to 5V if you are using a 5V arduino. The circuit should also work with a 3.3V Arduino (the minimum gate trigger voltage for the 2N7000 MOSFET is 3V), although ensure all voltages are correct.
The following is a rough schematic – all ground points need to be linked (as per the breadboard layout).
Fan PWM Controller Schematic
The 10k resistor (R1) is a pull down resistor and is needed to control the input to the MOSFET – without this the MOSFET might get very hot and fail if the Arduino is removed or if the connected pin is set as an input. The resistor is best located as close to the MOSFET gate pin as possible. The Diode (D2) (yes, the numbering system is wonky) dissipates the back EMF generated by the fan when the supply is cut. The MOSFET (Q3) switches the 12V supply (on the low side of the fan) based on the PWM signal from pin 10 on the Arduino, while effectively isolating the Arduino from the 12V and preventing damage. On its own, the Arduino would not be able to provide 12V, and can not provide the 180mA required by the fan I am using. The 2N7000 MOSFET is actually able to switch voltages up to 60V, although that is more than my fan can handle.
Once I had programmed the Arduino, I disconnected the DTR pin from the USB adapter to prevent my computer from resetting the Arduino constantly – this will not be possible so easily if you’re using an Arduino Uno. The trick I like to use to do this with an Arduino Pro Mini is as follows :
When soldering headers onto the Arduino Pro Mini, replace the supplied male header with a female header – this makes programming the boards much easier as the USB adapter has male headers.
Once programming is completed and you do not want the board to reset when a serial connection is established, place a 5 pin female header with extended pins (wire wrap / pass through style) between the Arduino and the USB adapter, taking care that the missing pin is the DTR (“GRN”) pin.
Note that it is still possible to program the board in this condition if you carefully press the reset button at the exact right moment. Also note that I actually use a 6 pin header with one pin trimmed off (because it reminds me what the header is for when I see it lying on my desk and I don’t throw it away).
Disable Reset
The Fan
I’ve used a small 40x40x20mm fan that I had in a cupboard. Other fans will be fine, although note that at these high PWM frequencies, I did have some difficulty with one cheaper fan where it was struggling to start.
To help with this, I’ve modified my Arduino software to give the fan a short burst of maximum speed (a fraction of a second) whenever the fan speed changes to help ensure the fan is running – while there is still a PWM duty below which the fan will not run, I have found that this specific fan generally runs down to as low as 50/255 (~20%) of full. Note the PWM duty does not correspond to fan speed – most of the variation available is between 200 and 255 (~80% to ~100%).
It is recommended that you put a switch in the 12V supply so that it is possible to turn off the fan easily. An improvement might be to take the pull up supply from the 12V using a regulator to generate 5V (for the whole circuit). Care should be taken to not back feed the computer’s USB with a slightly different 5V supply. There is a built in regulator on the Arduino Pro Mini which could be used for this, where 12V could be provided to the “RAW” pin, although 12V is the maximum recommended voltage for this regulator and it might get warm with sustained use. This would be a good option if you were also measuring temperatures using the Arduino in another application.
The Stand
A quick and easy way to make an adjustable stand for a fan is to use a piece of stiff wire, bent into shape through two of the fan’s screw holes. I’ve used a piece of stainless steel welding wire as can be seen in the following photograph.
Fan and Stand
The wire is in one piece and crosses the front of the fan between the two screw holes (on the other side of the fan from the camera). Pliers will make bending the wire easier.
Arduino Software
/******************
* Arduino High Frequency PWM Fan Controller Code
* https://elephantandchicken.co.uk/stuffandnonsense
* Circuit :
* Connect the gate of a 2N7000 to arduino pin 10.
* Connect a 10k Resistor between the gate and 5V.
* Connect the source pin to ground.
* Connect a 1N4007 diode between the drain pin and 12V with the band facing 12V.
* Connect a fan between the 12V rail and the drain pin.
* Remember to connect the grounds for the 12V and 5V circuits!
* Do not mix 12V and 5V!
* If in doubt, details of the circuit and software for controlling from linux
* are on my website
*******************/
int fan = 10; // set fan output pin
int fanspeed = 255; // start full speed
// for SerialEvent
String inputString = "";
boolean stringComplete = false;
void setup() {
// set the fan pin as an output
pinMode(fan, OUTPUT);
// adjust the PWM speed to make it fast enough that you can't hear it
// see : https://playground.arduino.cc/Main/TimerPWMCheatsheet
TCCR1B = (TCCR1B & 0b11111000) | 1; // hard coded for pins 9 or 10
// Start serial - doesn't need to be very fast
Serial.begin(9600);
Serial.println("\nPWM Fan Controller Started");
// For safety, as we don't know what is happening yet, turn the fan onto full
digitalWrite(fan, HIGH);
}
void loop() {
if(stringComplete){ // We've recieved a message
// reset the serial variables ready for the next message
String msg = inputString; // store locally so serialEvent can get back to capturing input
inputString = "";
stringComplete = false;
if(msg.startsWith("s")){ // "set" command
if(fanspeed!=msg.substring(1).toInt()){ // if the requested speed is different...
fanspeed = msg.substring(1).toInt(); // update the fan speed
digitalWrite(fan, 1); // these two lines help with a stalled fan...
delay(50); // by ramping the speed to full with no PWM for a short period
analogWrite(fan, fanspeed); // set the new PWM duty
}
Serial.println(fanspeed); // confirm the new speed to the host
}else if(msg.startsWith("c")){ // "check" command
Serial.println(fanspeed); // the host has asked what PWM duty we're currently using
}
}
}
void serialEvent() {
// Standard serial code from "SerialEvent" example
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n' || inChar == '\r') {
stringComplete = true;
}
}
}
Linux Software
Due to the limitations of my knowledge in various languages, I’ve used a mixture of bash and python as well as an existing piece of software to achieve what I wanted. My objectives were to continually monitor the external hard disk temperature, and set the fan speed based on this temperature. First things first, I used the “Disks” utility on Ubuntu to identify the external disks location – for exampe : /dev/sdc
The path “/dev/sd*” (where * is a letter of the alphabet) should exist for each connected disk, the similar files with a number on the end as well represent individual partitions and we are not concerned with these at the moment.
Next identify the serial port – with the adapter connected, type “ls /dev/ttyUSB*” at the command line. If you’re lucky, you will get a single result called “/dev/ttyUSB0” or similar. Note this can and does change, especially when you’re plugging and unplugging USB adapters, so you might need to re-check. If the previous command doesn’t return anything, try “ls /dev/tty*”. This will return a long list – ignore all entries which are just “/dev/tty#”, “/dev/ttys#” or “/dev/ttyprintk” where “#” is a number. Look at what else is there… unplug the adapter and run the command again. What is different? Plug the adapter back in again – does it re-appear? Whatever appears and disappears when you plug and unplug the adapter is the serial port you are looking for. As mentioned, the number might change as you are messing around.
Make a note of the disk path and serial port path. Mine are “/dev/sdc” and “/dev/ttyUSB0”.
Software which might need installing :
watch (sudo apt-get install watch) – allows you to run a command every n seconds
hddtemp (sudo apt-get install hddtemp) – reports the identified disk’s temperature
pyserial (pip install pyserial) – a python library to work with serial ports
Create a folder and move into it (to do this in the command line, use mkdir HDDTemperature && cd ./HDDTemperature to create a folder called HDDTemperature at your current location). Create three plain text files called hddFanControl.sh, hddFanControl.py and run.sh using your favourite text editor. Enter the following scripts into each respectively :
# Script to check a hard disks temperature, and send a fan speed over serial
# Usage :
# run.sh /dev/sd* /dev/ttyUSB*
# Ensure run.sh, hddFanControl.sh and hddFanControl.py are all in the current
# active directory.
# Note you need permission to access both the hdd and the serial port
# Note you'll need to disable reset on the MCU
# Serial fan controller should accept speed settings in the format s[0-255]
# where [0-255] is the pwm value between 0 and 255. Note most speed control
# is between 200 and 255, and often a fan needs 255 to start (due to the high
# pwm frequency (I'm using 31khz I think - there aren't many options on an 8
# bit AVR, just 60khz and 30khz which don't create noise. 60khz struggled to
# start the motor. AVR code I used to set the pwm speed was :
# TCCR1B = (TCCR1B & 0b11111000) | 1;
# and I'm using pin 10 (this command would also work for pin 9)
# be warned that messing with these pwm settings impacts other timing commands
#
# https://elephantandchicken.co.uk/stuffandnonsense
# 12/12/2018
# hdd location
VARHDD="$1"
# serial port
VARSER="$2"
TEMPERATURE=`hddtemp $VARHDD | grep -oh "..°C" | grep -ohE "[0-9]{1,4}"`
echo "Selected disk temperature is $TEMPERATURE°C"
python ./hddFanControl.py $VARSER $TEMPERATURE
# Script to check a hard disks temperature, and send a fan speed over serial
# Usage :
# run.sh /dev/sd* /dev/ttyUSB*
# Ensure run.sh, hddFanControl.sh and hddFanControl.py are all in the current
# active directory.
# Note you need permission to access both the hdd and the serial port
# Note you'll need to disable reset on the MCU
# Serial fan controller should accept speed settings in the format s[0-255]
# where [0-255] is the pwm value between 0 and 255. Note most speed control
# is between 200 and 255, and often a fan needs 255 to start (due to the high
# pwm frequency (I'm using 31khz I think - there aren't many options on an 8
# bit AVR, just 60khz and 30khz which don't create noise. 60khz struggled to
# start the motor. AVR code I used to set the pwm speed was :
# TCCR1B = (TCCR1B & 0b11111000) | 1;
# and I'm using pin 10 (this command would also work for pin 9)
# be warned that messing with these pwm settings impacts other timing commands
#
# https://elephantandchicken.co.uk/stuffandnonsense
# 12/12/2018
import time
import serial
import sys
from math import log
# How aggressive to make the fan curve? 0.4 is normal, 0.1 ramps up quickly
# at the start then levels off, 1 is linear (pwm duty, not cooling), 2 mainly
# ramps at the top end (would be basically off until the temp was at the top)
fanCurve = 0.4
Temperature = int(sys.argv[2])
maxTemp = 50
minTemp = 30
tempRange = maxTemp-minTemp
tempLift = Temperature-minTemp
if tempLift <= 0:
pwmDuty = 0
elif tempLift >= tempRange:
pwmDuty = 255
print "\nWarning! Hard Disk is hot!"
print "Disk is currently : " + str(Temperature) + " degrees C"
else:
var1 = (tempLift**fanCurve)
var2 = (tempRange**fanCurve)
pwmDuty = int(255*var1/var2)
print "\nCurrent Temperature : " + str(Temperature)
print "Current Target PWM setting : " + str(pwmDuty)
ser = serial.Serial(
port=str(sys.argv[1]),
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
ser.isOpen()
#flush with an empty line
ser.write('\n')
time.sleep(0.1)
ser.flushInput()
# moved the following into the mcu
#if pwmDuty > 0:
# # make sure we are not stalled
# ser.write('s255\n')
# time.sleep(0.1)
#check current setting
ser.write('c\n')
time.sleep(0.1)
out = ''
while ser.inWaiting() > 0:
out += ser.read(1)
if out != '':
print "\nMCU previous PWM was : " + str(int(out))
#send pwm setting
ser.write('s' + str(pwmDuty) + '\n')
# pause and see if there was a response
time.sleep(0.1)
out = ''
while ser.inWaiting() > 0:
out += ser.read(1)
if out != '':
print "MCU current PWM is : " + str(int(out))
ser.close()
exit()
# See comment in hddFanControl
# https://elephantandchicken.co.uk/stuffandnonsense
# 12/12/2018
watch -n60 ./hddFanControl.sh $1 $2
Back at the command line, enter the following three commands to convert the files into runnable software :
chmod +x ./hddFanControl.sh
chmod +x ./hddFanControl.py
chmod +x ./run.sh
To run the software, ensure that the Arduino is powered and connected to the computer through the USB adapter, then apply power to the fan. The fan should start at maximum speed.
You’ll need the disk and serial port paths from above to run the software, once you have them and have checked they are correct, enter the following (but using your hard disk and serial port) :
sudo run.sh /dev/sdc /dev/ttyUSB0
If everything works correctly, you should see something like the following, which will update every 60 seconds :
Screenshot
To stop the program, press Ctrl-C. Once you’re finished with the fan, power down the 12V fan supply and the Arduino.
Changing Parameters
To change the temperature update frequency, you will need to edit the file run.sh. The interval between measurements is represented by the 60 in “-n60” and can be replaced by other durations in seconds. To change the interval to be two minutes, run.sh would need to be changed to :
# See comment in hddFanControl
# https://elephantandchicken.co.uk/stuffandnonsense
# 12/12/2018
watch -n120 ./hddFanControl.sh $1 $2
All other parameters which can easily be modified are contained within the python file hddFanControl.py and allow the “normal” temperature range, and temperature/PWM response curve to be modified. Normal temperatures are defined by the variables maxTemp and minTemp (set to 50 and 30 respectively in the provided code). When the measured temperature is outside of this range, the fan duty will be pegged at either 0% (30°C or less) or 100% (50°C or more). These values can be modified the shift the operating temperature range if needed.
The temperature/PWM response curve is modelled as the temperature above the minTemp raised to a power (a variable called fanCurve). By adjusting the power, the characteristic of the curve can be adjusted. By default I am using a power of 0.4, which works well for my use case. The following plot shows the impact of varying the value of fanCurve.
PWM Plot
Adjusting the value allows the user to modify how early or late the % duty increases. Note that this only relates to the PWM duty and not fan speed. I have generally found that most of the variation in fan speed is observed in the last 25% of PWM duty.
Note that modifying the fanCurve variable is the best way of adjusting the balancing temperature of a specific state. Using 0.4, I was able to achieve a stable 37°C disk temperature, which was considered satisfactory, and comparable to the temperatures of my internal hard disks.
Conclusions
If you’re wondering, the file copy still hasn’t finished. (Update : it finally has).
I recently purchased a Atmel ATmega128 breaout board designed by LogiFind, called the ReadyAVR-64. The company seems to be imitating Mikroelektronika with their naming conventions and produce intermediately priced educational boards. They provide some examples and software, oriented around Windows as a host platform for most of their boards. I have a couple of examples for there wares, from the giant “EasyAVR128” to the more basic “ReadyAVR-28” (which I plan to swap a ATmega328 into – they do a board with one pre-installed, but it costs more). Currently, the documentation download link on their website for their ReadyAVR-64 board seems to be broken.
Despite being a blue PCB in all adverts etc. the board I received in the post was green. I had some minor postage issues, with my package been returned to sender for an unknown reason, but the seller was very honest and quick responding and the item arrived by airmail a few days after I reported my concerns.
ReadyAVR-64
Upon getting my board in the post, the first thing I did was swap out the crystal oscillator for a turned pin socket. There are two reasons for this – firstly the pre-installed crystal was an odd speed (7.3728mhz – I prefer 16mhz), and secondly, a socket means I can change the speed as I wish. Making this change requires your usual component desoldering – I used some flux, an iron and some solderwick – once the crystal was out of the board I finished clearing the holes with a solder sucker. Break off a 3 long piece of turned pin female header and solder it in. You don’t even need to remove the middle pin as there is an unconnected hole already on the PCB.
The next thing I did was replace the pre-installed bootloader with a variant of optiboot. I can’t remember exactly where I got it, but the hex file is here. This USB bootloader uses the PE1, PE0 serial port and so I had to switch the jumpers on JP2 for it to work. Loading in the new bootloader is done through the ISP6 or ISP10 ports. I used my STK500 with AVRdude, as I’ve had some difficulties programming AVR128s with my usbasp in the past. It should be possible to follow “Arduino as ISP” instructions to reflash the board. I wont go into depth here. At some point I’ll write a guide to reflashing bootloaders onto AVRs, but there are already a lot of guides out there. For reference, I used the following two AVRdude commands to setup the bootloader and fuses on my board :
At this point, if you wish to program the board using the Arduino IDE, you will need to install MegaCore. This adds extra microcontrollers, including the ATmega128 to the boards menu in the Arduino IDE. Installation is described in the “How to Install” section of the linked github page.
As I couldn’t find any documentation on the board due to the broken download link, I experimented and followed traces on the board until I worked out the following. Note that the LEDs are Active Low (setting the connected pin on the microcontroller to High turns them off).
LED0 = Arduino Pin 28 (PC0)
LED1 = Arduino Pin 29 (PC1)
LED2 = Arduino Pin 30 (PC2)
LED3 = Arduino Pin 31 (PC3)
BOOT = Arduino Pin 37 (PA7)
The Joystick is connected to Port B, but required the chip’s internal pullups to be enabled before it works correctly. One way this can be done in the Arduino IDE is by using digitalWrite to set the pin HIGH after having set it to be an input. Connections are as follows :
Joystick Up = Arduino Pin 9 (PB1)
Joystick Down = Arduino Pin 11 (PB3)
Joystick Left = Arduino Pin 10 (PB2)
Joystick Right = Arduino Pin 8 (PB0)
Joystick Click = Arduino Pin 12 (PB4)
Note that when you trigger two options at once, say for up and right, or left and click, all 5 pins trigger. The joystick connections are also Active Low, meaning the input goes low when the joystick is triggered.
The following Arduino example shows the functionality of both the LEDs and the joystick.
int LEDS[] = {28,29,30,31,37};
int Inputs[] = {8,9,10,11,12};
void setup() {
for(int x = 0; x<5; x++){
pinMode(LEDS[x], OUTPUT);
digitalWrite(LEDS[x], HIGH);
}
for(int x = 0; x<5; x++){
pinMode(Inputs[x], INPUT);
digitalWrite(Inputs[x], HIGH); // enable pullup
}
int LED = 0;
while(LED<5){
pinMode(LEDS[LED%5], OUTPUT);
digitalWrite(LEDS[LED%5], LOW);
delay(250);
digitalWrite(LEDS[LED%5], HIGH);
delay(250);
LED++;
}
}
void loop() {
for(int x = 0; x<5; x++){
if(digitalRead(Inputs[x])==LOW){
digitalWrite(LEDS[x], LOW);
}else{
digitalWrite(LEDS[x], HIGH);
}
}
}
As I add config files for different AVRs to my AVRprog2 setup, I intend to detail them here. Please see my other post here, for how to set AVRprog2 up on Linux and get it working with the Arduino IDE.
These files should be saved as text files in the style of (for the ATmega16) “atmega16.xml”, and placed in the folder “/usr/local/share/avrprog2/”. Super user permissions are required.
Additional Configuration Files :
The following are non-standard implementations – note they may contain errors.
Note – This is a draft version of this post. I need to take some photos and perhaps adjust the contents. I’ve also not proofread the text yet.
TL;DR
This post got a bit excessively long as I tried to include a bit of detail around the instructions. I probably should have kept it short and to the point. To overcompensate, here is a unhelpfully concise version of the instructions :
Add “https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json” to the “Additional Boards Manager URLs” field in the Arduino IDE preferences (a comma is required between each URL.
Install MiniCore within Tools>Board>Boards Manager
Place Chip in development board, connect USBasp to development board, plug USBasp into computer
Load your sketch, select Sketch>Upload Using Programmer
Done
Introduction
Often, if you’re interested in adding a small amount of intelligence to something your building or modifying, the resources of a full blown Arduino are overkill. A great way of getting the many of the benefits of the Arduino ecosystem in a cut down package and at a lower cost is to use a standalone AVR chip similar to the one found in an Arduino Uno. The following instructions discuss using an ATmega8A chip, in the DIP 28 package, although the process is very similar for other AVR microcontroller (MCU) chips. I like the ATmega8A because while it has only 1/4 of the program memory of the ATmega328P found in most Arduino Unos and many other Arduino variants, it can be purchased for less than 60p in small (x10) quantities.
Instructions to this end are reasonably readily available on the Internet already, but I’ve recently bought some parts for my dad and so wanted to pull a guide together, specifically for the things I know he is using.
Only the ATmega8A is actually required, as on the assumption you have another Arduino available, you can program the chip from another Arduino in a breadboard. How to do this is covered elsewhere in detail.
MCUDude has produced a number of useful additions to the Arduino IDE which allow you to easily program a large number of stand-alone AVR MCUs. These can be found here.
The ATMega8A
<picture>
The ATmega8A uses the same core as the ATmega328, but has a reduced feature set, including fewer PWM outputs, less RAM, less EEPROM and less flash memory for programs. Here are the basic specifications :
Maximum speed 16MHz (with external crystal)
8KB flash memory for programs
1KB SRAM
0.5KB EEPROM
While the chip can use an external crystal oscillator of up to 16MHz to control its speed, it (and other AVRs) also include an internal RC (Resistor Capacitor) oscillator, which can be used to run the chip at 8MHz with no external components. Using the chip in this mode allows for very streamlined operation as you can run your software on the chip and not need a single external component other than the wires providing power… although a MCU circuit with no external components or connections might not be very exciting, or much use at all. What it does mean is that you only need to add what you want.
While 8MHz is half the speed of a standard Arduino Uno, it is still amazingly fast (on an AVR it is approximately 8,000,000 processor level operations per second). More than enough for many projects.
The USBasp
<picture>
This programmer can be bought for not much money from ebay and seems to work perfectly well for almost all of my needs. The only time I’ve needed anything more comprehensive was to recover “bricked” chips, where fusebits (low level settings on the chips which define things such as operating speed or programming method) have been incorrectly set etc. Note : never throw out a chip that wont work unless you saw the magic smoke leave it – I’ve not once irreparably damaged an AVR chip no matter how hard I’ve (accidentally) tried.
If you’re feeling up to the challenge, you can even make your own, with some guidance available at this website, which I assume to be the original developer’s site. Making your own is especially relevant as they can be made using the ATmega8 we’re working with.
This programmer differs from using the USB port directly, or using an FTDI (or similar) USB to UART serial board to program an AVR MCU / Arduino in that it directly programs the chip without the need for any software to be already running on the chip. Part of the Arduino ecosystem is the use of a small program called a “bootloader”. This program runs when the chip is first powered on or reset and looks to the serial port for communications indicating that it should start reprogramming the remainder of the chip with a new program being fed in over serial. When a new chip arrives from the factory, it does not come pre-loaded with this bootloader and so another method (an in circuit programmer) is required to load in programs, or even a bootloader. Most ISPs use the SPI pins on the AVR MCU.
ATmega8, 48, 88 Development Board
<picture>
SOME ASSEMBLY REQUIRED. This board should also program the ATmega168 and ATmega328 – I’m not certain why they haven’t included these in the ebay listing. The board is nothing special, but is useful because of a number of features.
The ZIF socket reduces the chance of damaging the chip or board
You don’t need to count pins working out where to plug in each wire from the programmer – the programmer plugs right in
The circuit includes a crystal oscillator, which makes the first programming easier
It is cheap and already exists!
Setting up the Software
Install the Arduino IDE if you don’t already have it installed. This is done by going to the Arduino website software download section and following instructions for your platform. Once you have installed the Arduino IDE, check it runs by launching it. If possible, confirm it functions with a regular Arduino board by loading the “blink” example into a board. If you are unsure how to do this, the getting started part of the official website may be useful.
Once you’re up and running, navigate to the “Preferences” dialog box through the “File” menu. You will be faced with something similar to the following :
Arduino Preferences
Note the “Additional Boards Manager URLs” edit field. In a fresh install this will be empty. Paste the URL between the following quotes (exclusive) into the field : “https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json”. If there is already something in the field, find the end and add a comma before pasting in the quoted URL. Close the Preferences dialog box by clicking the “OK” button.
Select the “Boards Manager” from the “Tools”>”Board” menu. The “Board” sub-menu may have the name of the currently selected board in its name just to make it impossible for me to be specific. There may be a flurry of activity while the software checks for updates to the available boards etc. Once it has finished, it is possible to search for specific boards. For some reason it doesn’t seem possible to search for the collection name, which would be sensible.
Boards Manager
In the example image above I have searched for “atmega4” as I knew that the “atmega48” was an option in the MiniCore collection of boards. Once you find MiniCore, select it and then click “Install”. Note the “Install” button is not visible until the collection is selected. Once the install is complete, close the dialog and have a look in the “Tools”>”Boards” sub menu. You should find that a number of new options have appeared under the greyed-out heading “MiniCore”. Select the option called “ATmega8”. You’ll then notice that a number of new / different sub-menus will appear in the “Tools” menu. These can be used to exactly describe how you plan to use your ATmega8. I intend to use the chips internal 8MHz oscillator and so I have set the various options as per the following image. You should do the same!
ATmega8 Options
So we have… ATmega8, 8 MHz internal, Disabled (default) and 2.7v. BOD stands for “Brownout Detection” – the chip will stop operating when the supply voltage drops below this value. Not something we’re specifically worried about here. I’ve never messed with LTO, but it stands for “Link Time Optimisation”.
Also note, that near the end of the “Tools” menu, there is a menu option called “Programmer” and I have selected “USBasp”. You should do the same.
Finally, from the menu “File”>”Examples”>”Basics” select the “Blink” example to load it. Replace all occurrences of “LED_BUILTIN” with “0” (excluding quotes). For convenience, you can copy the following into a new sketch if you prefer :
/*
Blink
Turns an LED on for one second, then off for one second, repeatedly.
Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
the correct LED pin independent of which board is used.
If you want to know what pin the on-board LED is connected to on your Arduino
model, check the Technical Specs of your board at:
https://www.arduino.cc/en/Main/Products
modified 8 May 2014
by Scott Fitzgerald
modified 2 Sep 2016
by Arturo Guadalupi
modified 8 Sep 2016
by Colby Newman
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Blink
*/
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 0 as an output.
pinMode(0, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(0, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(0, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Click the “Verify” (tick) button in the top left of the sketch window to make sure the sketch compiles with no errors. If there are errors, double check that firstly, you’ve make the LED pin modifications correctly, haven’t accidentally introduced any errors into the code, and have correctly installed MiniCore. You may also want to check that the correct board settings were selected.
Once / if the code compiles without errors, we’re ready to move on to programming a chip.
Programming a Chip
Ensure the locking mechanism on the development board ZIF socket is unlocked / open (leaver up). Place the ATmega8A chip into the ZIF socket with pin 1 (marked by a little circular indent on the top of the chip) near the reset button (the far end from the 5×2 connector). Lock the chip in place by lowering the leaver on the socket. When soldering the ZIF socket to the board, I recommend ensuring the leaver is at the reset end of the board.
Plug the 5×2 cable connector from the programmer in – one end in the programmer, the other in the development board. Note the notch should face inwards towards the centre of the development board. If it doesn’t, you might have soldered the connector the wrong way around!
<picture>
Taking care not to short the underside of either the development board or programmer on anything metallic (a USB extension cable might help here), plug the USBasp into your computer. You shouldn’t need drivers on a Mac or Linux, but you may have to set up permissions on Linux. Check here for the (permanent version please) solution on Linux.
Bootloader and Fuses
Return to your modified “Blink” sketch. You may want to do a Save As… to keep the modifications for the future. Then, just once, the first time you program your new chip, with the USBasp and development board connected, select the menu item “Tools”>”Burn Bootloader”. This will load bootloader code into your ATmega8, but more importantly, it will set up the various fuses (low level settings) to tell the chip that you want it to operate using its internal 8MHz oscillator and any other settings recommended by the MiniCore software. The IDE should tell you that the bootloader was successfully uploaded. If it didn’t, please check that everything is connected properly and the correct options in the “Tools” menu, as detailed above, have been selected.
The Program
The final, and one of the easiest steps is to load our blink sketch into the chip. This is done by going to the “Sketch”>”Upload Using Programmer” menu item. A shortcut for this is to Shift+Click on the right facing arrow that you would use to ordinarily program an Arduino. If you notice, the “Upload” text to the right of that cluster of buttons changes to “Upload Using Programmer” when you hold the mouse over the Upload button and press the Shift key.
Upload
If you look at the development board, one of the LEDs on the board should now be flashing. This LED is connected to pin 0 on the board. If the LED is not flashing, check the computer screen to see that the program successfully uploaded.
Another advantage of programming a chip in this way is that you do not need the bootloader (when you “Upload Using Programmer” it actually overwrites the bootloader – but retains the fuse settings). This means you can use the full amount of program flash memory in the chip for your own code. While the bootloader isn’t huge, this can make the difference between your software fitting in the chip or not – especially when using one of these cheaper AVRs with less room available to begin with.
Breadboard
Now that you (should) have a program running on the chip, you can transfer the ATmega8A to a piece of breadboard. To recreate the blinking LED circuit in its minimum form, you will need :
One piece of breadboard long enough to hold the ATmega8A
Something that can provide 5v
Two wires for 5v and GND
A 1k ohm resistor
An LED
Wire up as follows :
Breadboard
Note that you don’t need the left most black wire as you can just separate the wires on the LED further to bridge back to the other black wire on IC pin 8 (8th pin counting anti-clockwise from the little black dot marking pin 1, not to be confused with Arduino digital pin 8, which is actually IC pin 14… just to confuse things!).
When working on your own projects, you will find the diagram linked here very useful. It details the features and names of various pins on the chip. Note the key item “Arduino Pin” as that is the name of the pin in the Arduino IDE.
Using AVRprog2 and an EasyAVR5A with the Arduino IDE
A few years back I bought myself a mikroe EasyAVR5A from the discount bin of an online store. Sadly, at the time, there was no way to use the built in USB programmer from any OS other than Windows, so I resorted to programming the board through a USBasp.
The mikroe EasyAVR5A
Jump forwards a while and a helpful university produced a Linux (and Mac) program compatible with the built in USB programmer. This can be found here. I have been using this software for a while and am very happy that it exists. To use it with the Arduino IDE, you need to add the MCUs you’re using (if you use an ATMega328p you can skip this as it is the standard chip in an Arduino Uno, although you will need to add it to the list of xml files which describe chips for the AVRprog2 software, described later for the ATMega32), build the project with “verbose” turned on in preferences, copy the path to the final mentioned .hex file, and paste it into the command line with the command to program the board. A little bit of a faff.
The mikroe AVRprog2
Messing about today I set myself a little challenge to see if I could add the avrprog2 program as a programmer within the Arduino IDE – I managed to get it working, so here are the directions on how. This should apply to other boards that use the mikroe AVRprog2 interface (labelled as AVRprog on the board, which causes confusion as there is a parallel interface programmer called the same).
1. Download, compile and install the github avrprog2 project. You can mostly follow their instructions, except you have to run autogen.sh before anything else (otherwise the configure script doesn’t exist). The listed dependencies are not helpfully named (some aren’t the package names), but a bit of googling gets it working. For reference, I ran the following commands to install :
2. Open the folder called “config”. Copy, then edit the file “atmega16.xml” to a file called “atmega32.xml” and then replace the contents with the following :
You don’t need to do this if you don’t plan to use the ATMega32A part, but I did and might as well include it. Once edited, save and copy to the folder “/usr/local/share/avrprog2/”. You’ll need super user permissions to do this.
I’ve uploaded a few more config files in this post. Note that I’ve included the default ones for reference. I’ll add more with time as I test more chips.
3. Install MightyCore as per the instructions on the github page.
4. Add the following to the MightyCore platform.txt file (mine was located in “~/.arduino15/packages/MightyCore/hardware/avr/1.0.8” – you can find the correct folder by going to Preferences in the IDE, then clicking on the link under “More preferences can be edited directly in the file…”, then navigating through ./packages/MightyCore/hardware/avr/1.0.8) :
6. Save both modified files, restart the Arduino IDE and… you should see a new entry called “avrprog2” in the Tools>Programmer menu.
7. Load your program, select the correct MightyCore chip (the board comes with an ATMega16), select the avrprog2 and other various settings for the MCU then…
8. Shift click the Upload button. If all goes well you should see the compile and then your program loading into the chip. I find I can’t program the board twice without powercycling between, and sometimes it doesn’t find the board for some reason (but that is the same when using the programming software from the command line.
Hope someone finds these instructions useful – they have been written at speed because I have somewhere to be. I may return to clean them up and add some pictures at a later date!
Note that I’ve not currently made modifications which allow you to flash the bootloader (I’ve not done anything that writes the fuses). The following two commands seem to work for Internal 8mhz and external crystal respectively :
The other day I got myself an UDOO x86 (specifically the penultimate “Advanced Plus” model). An interesting device that sits between most of the ARM SBCs and an older PC in performance. Steam games such as Bastion, Rogue Legacy and Super Meat Boy seem to work OK, Youtube plays fullscreen just fine although Steam game preview videos lag – watching processor usage I suspect that the graphics chipset (Intel 400) is not providing any acceleration in this context. I was not impressed by the fact that the quoted CPU frequencies are a misleading “Up to 2.24Ghz”, which really means, “2.24Ghz boost, 1.7Ghz operation” – I have not seen the board exceed 1.7Ghz while running Linux.
UDOO x86 Top
Another unusual feature of the board is that the built in eMMC shows up as an SD card. Probably unrelated, but I had more difficulty installing dual boot Linux on the internal eMMC and a plugged in M.2 drive than I ever have had on any machine – many of which weren’t even intended to run Linux! The main issue related to an error when installing GRUB
UDOO x86 Bottom
I spent a huge amount of time looking for a 2260 M.2 ssd (60mm length) and couldn’t find one in stock anywhere of a brand I’d trust. Suddenly I realised that the offset between the two sockets meant that a 2242 (42mm) board would fit in the top slot using the 30mm screw fitting for the lower slot (intentional I’m sure, but not obvious!). 42mm boards seem to be more common and so I was able to get a 64GB Transcend part.
I got the offered fan with my device, but it really isn’t needed. Getting the fan to start with the default settings is difficult as even at full processor usage (all cores) I wasn’t able to get the processor hot enough to need it. I poked the internet and found the instructions for the BIOS. There was a section that mentioned editing the default fan temperatures and speeds so I did a bit of a tweak. The fan now starts at a lower temperature, and runs at a lower speed.
BIOS Top Level Menu
To change your fan settings, press escape as soon as the board powers on to get to the bios homescreen. Selecting the SCU option leads to a detailed settings page which looks like the following screen :
BIOS SCU Page
Selecting the “Power” section from the options at the top, you are presented with various options including one called “Thermal Zone Configuration”. As per page 54 / section 4.5.3 of the manual you can edit various settings, I’ve changed “AC1 Temperature” to 55°C and “FAN Duty Cycle (%) Above AC1” to 50%. This means the fan is nice and quiet when it does start.
I’ve yet to experiment with much on the board. I’m interested in having a look at the Arduino capabilities – care should be taken as next to the Arduino headers are some lower voltage (1.8v) pins for the main chipset. Wiring something into these accidentally would likely cause damage.
I’ve quickly cobbled together a rechargeable lithium battery circuit and stuck it into a box with an Arduino, a temperature / humidity sensor and a temperature / pressure sensor.
It hasn’t exploded yet.
This was the circuit I used to test it was working (using the battery charger and step up DC-DC converter to power my flammable gas sensing circuit, because it was within reach).
This evening I re-wrote an Arduino program of mine that takes measurements from a DHT22 temperature / humidity sensor and BMP180 temperature / pressure to make it work with and Arduino Nano with an LCD screen attached. I’ve not used a Nano in ages, but sadly, I needed the 3.3v regulator to drive the BMP180. Hopefully it won’t be drawing much current and so not wasting much energy, after I went to the effort of using a reasonably efficient step up converter. I did check, and the voltage straight from the battery is also too high. Future plans include… not using 3.3v sensors.
Here is a video of the box running off the battery.
I’ll tidy up the circuit – perhaps move it from breadboard and a pile of bits onto protoboard, make the charging port accessible, add a power button, menu buttons, battery voltage monitoring, auto power down for low battery / after inactivity and perhaps add an external 1 wire bus for DS18b20 sensors. At that point I’ll document what I’ve done a little better.
As I previously mentioned, I got a number of gas sensors. The intention is to use one to build a gas leak detector for a neighbour who has no sense of smell and runs a burger van. After reading the datasheets for a number of possible sensors including the MQ-2, MQ-5 and MQ-6, I decided to use the MQ-6 as it seemed best suited. The MQ-2 is sensitive to smoke, which rules it out and the MQ-6 appears to be more sensitive to LPG than the MQ-5, judging by the datasheets. The sensors I have come on breakout boards. My MQ-6 board is powered from 5v and has a digital output with the threshold set by a potentiometer on the board in addition to the analogue output. The on board comparator (I’ve not looked into what form it takes) lights an LED when the gas concentration exceeds the level set by the potentiometer, but be aware that a digital LOW corresponds to a positive identification of gas, and a digital HIGH corresponds to the concentration being lower than the set threshold. The datasheet states that the sensor consumes <750mW, mine seems to be using something between 400 and 500mW.
I have been using an Arduino Pro Micro board because they are convenient for prototyping in breadboard as they have a built in USB port and a DIL layout. I may switch to a ATTiny85 or a ATMega328 in the future. The Pro Micro is built around the ATMega32u4 chip and can be bought cheaply from alibaba, or almost as cheaply using paypal from banggood.
After writing some comments in an empty sketch to give me the structure of what I wanted to do, I wired up the sensor, along with an LED (unfortunately the Pro Micro only has LEDs for power, TX and RX) and a push-to-make switch to act as an “action” button. I later added a 2N7000 MOSFET, which I am using to switch power to the sensor – this is being used to reduce the power consumption after 10 minutes and reduce battery usage should someone forget to turn the device off!
Quick diagram (ignore the colours in the photo, they’re misleading) :
The sensor seems to need bedding in and so the values I’ve used for alarm thresholds are only temporary. Once it stabilises (it is referred to as a “burning in” period elsewhere), I’ll re-visit the values.
The current code is as follows :
// LPG Gas Detector
//
// Using the MQ-6, although with changes to detection values,
// you could easily use the MQ-5, or perhaps the MQ-2.
// No responsibility is taken for failure to detect gas.
// Samplerates are approximate for simplicity.
// 6th Feb 2016 version 0.1
int heaterPin = 9; // connect a MOSFET or transistor to this pin to
// drive the Heater
int DIn = 10; // connect the digital trigger from the sensor
int AIn = A0; // connect the analogue input from the sensor
int LED1 = 2; // LED
int action = 7; // action button
unsigned long stopTime;
byte heaterOffMinutes = 10;// time before auto power down heater
byte heaterDelayMinutes = 3;// time to wait for heater to start
//byte heaterDelayMinutes = 1;// time to wait for heater to start
byte samplesPerMinute = 30;// number of samples in a minute
byte reheatDelayMinutes = 1;// Time to reheat after low power mode. Should really be 3 minutes.
boolean debug = true;
int lowAlarm = 250;
int medAlarm = 375;
int highAlarm = 500;
void setup() {
unsigned long heaterOff = heaterOffMinutes*60L*1000L;// min*seconds*ms
int heaterDelay = heaterDelayMinutes*60L;// min*seconds
if(debug){
Serial.begin(115200);
}
delay(3000);
if(debug){
Serial.println("Setting up pins...");
}
pinMode(DIn,INPUT);
pinMode(AIn, INPUT);
pinMode(LED1, OUTPUT);
pinMode(heaterPin, OUTPUT);
pinMode(action, INPUT);
digitalWrite(LED1, LOW);
if(debug){
Serial.println("Turning on heater...");
}
// Turn on heater
digitalWrite(heaterPin, HIGH);
if(debug){
Serial.println("Waiting for heater to warm up...");
}
// Wait Three minutes before giving readings
heat(heaterDelay);//heaterDelay in seconds
// Record target stop time for auto heater off (save the battery!)
stopTime = millis()+heaterOff;
if(debug){
Serial.println("Heater will stop at : " + String(stopTime,DEC));
}
}
void loop() {
// Go to sleep after 10 minutes? At least turn off heater.
if(millis() < stopTime){
if(debug){
Serial.println(String((stopTime-millis())/1000, DEC) + " seconds until sleep. Taking Reading...");
}
int AVal = analogRead(AIn);
boolean DVal = !digitalRead(DIn);// 0 is high
if(debug){
Serial.println("Digital is : " + String(DVal, DEC));
}
if(debug){
Serial.println("Analogue is : " + String(AVal, DEC));
}
if(AVal > lowAlarm){
if(AVal > medAlarm){
if(AVal > highAlarm){
//HighAlarm
digitalWrite(LED1, HIGH);
if(debug){
Serial.println("Alarm! High");
}
}else{
//MedAlarm
if(debug){
Serial.println("Alarm! Medium");
}
digitalWrite(LED1, LOW);
delay(10);
digitalWrite(LED1, HIGH);
delay(50);
digitalWrite(LED1, LOW);
delay(200);
digitalWrite(LED1, HIGH);
delay(50);
digitalWrite(LED1, LOW);
delay(200);
digitalWrite(LED1, HIGH);
delay(50);
digitalWrite(LED1, LOW);
}
}else{
//LowAlarm
if(debug){
Serial.println("Alarm! Low");
}
digitalWrite(LED1, LOW);
delay(10);
digitalWrite(LED1, HIGH);
delay(50);
digitalWrite(LED1, LOW);
delay(200);
digitalWrite(LED1, HIGH);
delay(50);
digitalWrite(LED1, LOW);
}
}else{
//NoAlarm
digitalWrite(LED1, LOW);
}
}// end of stopTime if
else{
if(debug){
Serial.println("Low Power mode");
}
//sleep mode instead of delay?
digitalWrite(heaterPin, LOW);
int y = 0;
for(int x=0; x<30; x++){
if(digitalRead(action)){
y++;
}else{
y=0;
}
if(y>2){
// Record target stop time for auto heater off (save the battery!)
digitalWrite(heaterPin, HIGH);
while(digitalRead(action)){
//do nothing
delay(100);
}
heat(reheatDelayMinutes*60L);
stopTime = millis()+(heaterOffMinutes*60L*1000L);
x = 30;
if(debug){
Serial.println("Heater will stop at : " + String(stopTime,DEC));
}
}
delay(2000);
}
}
delay(60000L/samplesPerMinute);
digitalWrite(LED1, LOW);
delay(10);
digitalWrite(LED1, HIGH);
delay(10);
digitalWrite(LED1, LOW);
}
void heat(int heaterDelay){ // heaterDelay in seconds
for(int x = 0; x< heaterDelay; x++){
boolean btn = false;
if(debug){
Serial.println("Readings start in... " + String(heaterDelay-x,DEC)+ " seconds");
}
//Serial.println(String(x, DEC) + " of " + String(heaterDelay, DEC));
digitalWrite(LED1, !digitalRead(LED1));
if(digitalRead(action)){
btn = true;
}
delay(1000);
if(digitalRead(action) && btn){
x = heaterDelay;
if(debug){
Serial.println("Warm up skipped...");
}
}
}
}
If you spot any errors, please drop me a message!
As always, the most difficult part of this project seems to be identifying a suitable power source and box. I’ve been using my USB meter to gauge how much energy the circuit uses – I estimate that I can run it with the heater on for 10 hours off four AA batteries. I’m struggling to identify a box that would easily allow the end user to change the battery without being forced to use a PP6 battery, which would be a waste of 4v. I’m not sure how accurate my little USB meter is, but it is very useful as I power a lot of my projects off computer USB ports or my USB battery packs!