💬 Various bootloader files based on Optiboot 6.2
-
I have added my atmega328 directory in a RAR file and uploaded it to the site.
This compressed file contains a directory structure that contains all bootloaders I use, and the extra files needed to make most of those available from the Arduino IDE.
To use it:
Close the Arduino IDE
Unpack the RAR file
Open the IDEThis compressed file needs to be unpacked inside the "hardware" directory which sits inside the Arduino Sketches directory. If you do not have a "hardware" directory inside the Arduino Sketches directory, then you need to make this first.
Then go inside the "hardware" directory and there unpack the RAR file.My directory structure looks like this:
[Arduino] [hardware] [atmega328p] [avr] [bootloaders] [myoptiboot] ... all the HEX files ... [variants] [28PinBoard] pins_arduino.h [32PinBoard] pins_arduino.h [40PinBoard] pins_arduino.h [44PinBoard] pins_arduino.h boards.txt platform.txt -
I'm finally managing to update my Arduino IDE and would like to ask how you have your boards.txt setup. Do you have your boards.txt file that is zipped up in your config zip file just located in the avr folder without running the default boards.txt file or are we supposed to merge your boards file with the original one? Back when i was developing my own boards, i seem to remember just running your board file without any of the default files....
Is this correct or do we merge them?
-
@GertSanders Awesome, thank you for uploading it as a .rar!!! So easy now :)
@Samuel235 You should be able to just copy the entire folder from the .rar file into your Arduino folder. I had to create a "Hardware" folder as it didn't exist. I'm on Windows 10 and it looks like this:

After closing/re-opening the Arduino IDE it looks like this:

-
The boards .txt and platform.txt files are not complete yet, and I still need to check and change the pins_arduino.h boards for the 40 and 44 pin atmega's. That is still on my to do list, but the structure is there already. I'm still learning from other hardware deployments how to define this in a practical way. Hopefully by sharing this will be improved.
-
@petewill - I do that, however i do already have the hardware folder (and its a clean install of windows and arduino IDE) and then inside the hardware folder i have the boards.txt file (the default one, the list that shows in the IDE without installing gertsanders'. So, i either need to put the new one in there and rename the old or to merge the two together.
Or am i getting this completely wrong some how?
EDIT: It was a mistake on my own part but will leave this comment here for anyone to see and to not make the same mistake as myself:
I was attempting to put it inside of the "arduino" folder that was inside of the hardware folder. My own fault XD
-
This post is deleted!
-
I'm slightly confused here...
I'm using a arduino nano, hooked it up to avrdude and read the fuses as Low:FF, High:DA, Extended:05. I then burn new fuses of Low:FF, High:DE and Extended:07. Burnt fine, so i go into arduino IDE and select the bootloader for 32pin, TQFP, 8MHz external crystal 38K4 D13 and then burn bootloader. I get a little warning but that is only because of the new IDE issues with extended bits ("You probably want to use 0xfd instead of 0x05 (double check with your datasheet first)."). But now the LED on the nano is blinking rapid then stop, then blinking rapid and then stop. I can't upload a sketch to the nano either now. I can however burn the old bootloader back on and upload like normal. What could be the issue here?
It almost seems like there is something wrong with the bootloader as it is uploading to it but the LED is blinking weirdly. May not be the bootloader itself, could just be some corruption as it gets uploaded....
-
I'm slightly confused here...
I'm using a arduino nano, hooked it up to avrdude and read the fuses as Low:FF, High:DA, Extended:05. I then burn new fuses of Low:FF, High:DE and Extended:07. Burnt fine, so i go into arduino IDE and select the bootloader for 32pin, TQFP, 8MHz external crystal 38K4 D13 and then burn bootloader. I get a little warning but that is only because of the new IDE issues with extended bits ("You probably want to use 0xfd instead of 0x05 (double check with your datasheet first)."). But now the LED on the nano is blinking rapid then stop, then blinking rapid and then stop. I can't upload a sketch to the nano either now. I can however burn the old bootloader back on and upload like normal. What could be the issue here?
It almost seems like there is something wrong with the bootloader as it is uploading to it but the LED is blinking weirdly. May not be the bootloader itself, could just be some corruption as it gets uploaded....
@Samuel235
If you are using a nano, what crystal is mounted on it ? Fast flashing indicates the processor is running faster then the expected 8MHz (expected by the timing routines of the bootloader). Could it be a 16MHz model ?
In that case you could try to upload a sketch at a higher speed: 76K8 baud.
Or you can try to load the bootloader for 16MHz/D13 (which in effect is the standard bootloader of an Arduino). -
I'm slightly confused here...
I'm using a arduino nano, hooked it up to avrdude and read the fuses as Low:FF, High:DA, Extended:05. I then burn new fuses of Low:FF, High:DE and Extended:07. Burnt fine, so i go into arduino IDE and select the bootloader for 32pin, TQFP, 8MHz external crystal 38K4 D13 and then burn bootloader. I get a little warning but that is only because of the new IDE issues with extended bits ("You probably want to use 0xfd instead of 0x05 (double check with your datasheet first)."). But now the LED on the nano is blinking rapid then stop, then blinking rapid and then stop. I can't upload a sketch to the nano either now. I can however burn the old bootloader back on and upload like normal. What could be the issue here?
It almost seems like there is something wrong with the bootloader as it is uploading to it but the LED is blinking weirdly. May not be the bootloader itself, could just be some corruption as it gets uploaded....
@Samuel235
It also seems the nano is in a reset loop. I'm at work so I can not check my Mac for the fuse settings I use. -
@Samuel235
If you are using a nano, what crystal is mounted on it ? Fast flashing indicates the processor is running faster then the expected 8MHz (expected by the timing routines of the bootloader). Could it be a 16MHz model ?
In that case you could try to upload a sketch at a higher speed: 76K8 baud.
Or you can try to load the bootloader for 16MHz/D13 (which in effect is the standard bootloader of an Arduino).@GertSanders Soon as i say the fast flashing I instantly thought that its running quicker than needed, but i had no idea about the resetting that you have pointed out, so thanks for pointing that one out. The reason i didn't even bother trying the 16MHz settings in fuses would be that because when i read the fuses of the arduino before i did anything, it indicated that it was running with fuses of 8MHz and the blink sketch was perfectly timed on those settings.... Could it be a miss read on the fuse settings maybe? Should i read at a slower speed when using avrdude?
The crystal is so small on the nano and i can't even see the engraving with a microscope properly either.
I can confirm that the 16MHz bootloader is working perfectly on this nano. Thanks.
-
I have been running your bootloader for all my nodes now and that works very well.
But there is something that surprised me. When I compile the next sketch and compare that with the Moteino bootloader it's substantially larger./*************************************************************************************** ** ** Outdoor sensor v1.0 Measuring temperature, humdity, pressure and light level ** Calculating a weather forecast with the height comensated air pressure. ** powered by a solar panel and a 1000mAh Li-Ion battery. ** ** Scraped together by D Hille. MySensors library by Henrik Ekblad et al. ** ** Heat index calculation from DHT library by Adafruit ** MAX44009 bij Rob Tillaart ** Weather forecast based on AN3914 by Freescale ** ****************************************************************************************/ // MySensors definitions //#define MY_DEBUG // Enable debug prints (6 kb flash space) //#define MY_DEBUG_VERBOSE_SIGNING // Comment out when no signing is used or when everything is OK (3 kb flash space) #define MY_BAUD_RATE 57600 // Set serial baudrate #define MY_RADIO_RFM69 // Enable and select radio type attached //#define MY_IS_RFM69HW // Comment out when using standard RFM69W #define MY_NODE_ID 110 // Delete to use automatic ID assignment //#define MY_CORE_ONLY /**************************************************************************/ // Transport /**************************************************************************/ //#define MY_TRANSPORT_WAIT_READY_MS 1000 //Start the node even if no connection to the GW could be made (disable for sensor nodes). #define MY_TRANSPORT_STATE_RETRIES 1 #define MY_TRANSPORT_MAX_TSM_FAILURES (2u) #define MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE (60*1000ul) /**************************************************************************/ // Security /**************************************************************************/ //#define MY_SIGNING_ATSHA204 //#define MY_SIGNING_SOFT //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //#define MY_SIGNING_REQUEST_SIGNATURES //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = 0,.serial = {0xD0,0xB1,0x90,0x99,0xC3,0x03,0x08,0xD1,0x34}}} //#define MY_RFM69_ENABLE_ENCRYPTION /**************************************************************************/ // Sensor definitions /**************************************************************************/ #define BATTERY_POWERED #define battUpdater 300 //Number of TX actions to count before a new battery status update is sent. #define MY_DEFAULT_TX_LED_PIN 5 // Comment out when no LED is attached. #define MY_WITH_LEDS_BLINKING_INVERSE #define SENSOR_TYPE 3 // Sensor types: // 0.: no climate sensor attached // 1.: RFM69 on-die Temperature sensor on the RFM69 module (whole integers only) // 2.: DS18B20 Dallas one-wire sensor(data pin D14) // 3.: HTU21D Temp/humidity (I2C) // 4.: BME280 Temp/humidity/pressure (I2C) (node will wake every minute to keep up with trend measureing) #define SENSOR_UPDATE 2 // Time in minutes the sensor sends an update //#define LIGHT_SENSOR_PRESENT // Comment out when not present. (I2C) (Light sensor will update every 60 seconds.) //#define INTERRUPT_SENSOR_PRESENT // Comment out when not present (e. g. motion sensor connect to D3) #define alti 57 //altitude offset to compensate the barometric pressure /**************************************************************************/ // Debug definitions /**************************************************************************/ //#define LOCAL_DEBUG //Comment out to switch all debug messages off (saves 2 kb flash) #ifdef MY_DEBUG //Differentiate between global debug including radio and local debug #define LOCAL_DEBUG //for the sketch alone. #endif #ifdef LOCAL_DEBUG #define Sprint(a) (Serial.print(a)) // Macro as substitute for serial debug. Will be an empty macro when #define Sprintln(a) (Serial.println(a)) // debug is switched off #else #define Sprint(a) #define Sprintln(a) #endif /**************************************************************************/ #include <Button.h> #include <SPI.h> #include <Wire.h> #include <MySensors.h> //#include <SparkFunBME280.h> //#include <MAX44009.h> // Uncomment library used in sketch #include <Adafruit_HTU21DF.h> //#include <OneWire.h> //#include <DallasTemperature.h> #include <Vcc.h> #define BMEaddr 0x76 #define Max44099Addr 0x4A #define sketchName "sensorNode(living)" #define sketchVer "1.0" #define sensorPowerPin 20 #define digitalSensorPin 14 #define analogSensorPin A0 #define oneWireBusPin 14 #define interruptPin 3 #define altSensorPin 18 #define altAnalogPin A4 #define sensorPowerPin 6 #define chanTemp 0 #define chanHum 1 #define chanHeat 2 #define chanBaro 3 #define chanDelta 4 #define chanLight 5 #define chanRate 6 #define chanInterrupt 8 #define PULLUP false #define INVERT false #define bounceTime 20 #define sleepWait 500 //Time to wait in ms before node sleeps (to be able to receive notification messages). bool battPower = true; unsigned long currTime = 0; unsigned long sleepTime = (60000 * SENSOR_UPDATE); unsigned long lastSensorUpdate; unsigned long nextSensor; unsigned long measureTime; int wakeReason = -1; int sendLoop = 0; bool updated = false; bool ACKed = false; int sensorFunc = 0; float sensorData = 0.0; float heatTemp = 0.0; float heatHum = 0.0; bool interruptState = false; bool lastInterrupt = false; bool sensorPresent = false; bool lightPresent = false; bool interruptPresent = false; int minuteCount = 0; bool firstRound = true; float pressureAvg; // average value is used in forecast algorithm. float pressureAvg2; // average after 2 hours is used as reference value for the next iteration. float dP_dt; const int LAST_SAMPLES_COUNT = 5; float lastPressureSamples[LAST_SAMPLES_COUNT]; bool startUp = true; bool metric = true; int battStatCounter = 0; const float VccMin = 1.8; // Minimum expected Vcc level, in Volts. const float VccMax = 3.0; // Maximum expected Vcc level, in Volts. const float VccCorrection = 1.0/1.0; // Measured Vcc by multimeter divided by reported Vcc /**************************************************************************/ // Library declarations /**************************************************************************/ // Uncomment necessary declarations. //RFM69 wireless; //OneWire OWB(oneWireBusPin); //DallasTemperature DS18(&OWB); //DeviceAddress DS18address; Adafruit_HTU21DF HTU = Adafruit_HTU21DF(); //BME280 BME; //Max44009 lightMax(Max44099Addr); //Button reedContact(interruptPin, PULLUP, INVERT, bounceTime); MyMessage msgHum(chanHum, V_HUM); MyMessage msgTemp(chanTemp, V_TEMP); //MyMessage msgBaro(chanBaro, V_PRESSURE); //MyMessage msgTrend(chanUniversal, V_VAR5); //MyMessage msgLight(chanLight, V_LEVEL); //MyMessage msgIntr(chanInterrupt, V_TRIPPED); Vcc vcc(VccCorrection); /**************************************************************************/ // Error messages /**************************************************************************/ #if (defined INTERRUPT_SENSOR_PRESENT && defined LIGHT_SENSOR_PRESENT && SENSOR_TYPE >= 4) #error Motion sensor can anly be combined with either I2C OR one-wire sensors, not both. #endif #if (defined INTERRUPT_SENSOR_PRESENT && (defined LIGHT_SENSOR_PRESENT || SENSOR_TYPE == 4) && defined BATTERY_POWERED) #error Interrupt sensor is not compatible with trend sensors like 'baro' and 'light' because the timer will misalign. #endif #if (SENSOR_TYPE > 4) #error Not a valid sensor type! #endif /**************************************************************************/ void before(void) { Serial.println("\nReading config..."); #ifndef BATTERY_POWERED battPower = false; #endif sensorFunc = SENSOR_TYPE; #ifdef LIGHT_SENSOR_PRESENT lightPresent = true; #endif #ifdef INTERRUPT_SENSOR_PRESENT interruptPresent = true; lastInterrupt = reedContact.read(); #endif #if (defined MY_SIGNING_SOFT || defined MY_SIGNING_ATSHA204) #define sendPause 100 #else #define sendPause 50 #endif } /**************************************************************************/ void setup(void) { pinMode(sensorPowerPin, OUTPUT); //switch on the sensor power digitalWrite(sensorPowerPin, HIGH); wait(50); //wait 50 ms for the sensors to settle. switch (sensorFunc) { case 0: break; case 1: sensorPresent = true; break; case 2: //DS18.begin(); //DS18.getAddress(DS18address, 0); //DS18.setResolution(DS18address, 10); sensorPresent = true; break; case 3: HTU.begin(); sensorPresent = true; break; case 4: //startBME(); sleepTime = 60000; sensorPresent = true; break; } #if (lightPresent) sleepTime = 60000; sensorPresent = true; #endif #ifdef MY_DEBUG //Differentiate between global debug including radio and local debug sleepTime = 30000; //for the sketch alone. #endif batteryStats(); Serial.println("\nDone. \n\nStarting program.\n"); currTime = millis(); } /**************************************************************************/ void presentation() { Serial.println("Start radio and sensors"); sendSketchInfo(sketchName, sketchVer); Sprint("\nPresent "); if (sensorFunc >= 1) { wait(sendPause); present(chanTemp, S_TEMP, "Climate", true); Sprint("temperature"); } if (sensorFunc >= 3) { wait(sendPause); present(chanHum, S_HUM); Sprint(", humidity"); //wait(sendPause); //present(chanHeat ,S_TEMP); //Sprint(", heatindex"); } if (sensorFunc == 4) { wait(sendPause); present(chanBaro, S_BARO); Sprint(", barometric"); wait(sendPause); present(chanDelta, S_CUSTOM); Sprint(" and rate"); } Sprintln(" sensor."); if (lightPresent) { wait(sendPause); present(chanLight, S_LIGHT_LEVEL, "Light", true); Sprintln("\nLightsensor "); if (sensorFunc < 4) { wait(sendPause); present(chanRate, S_CUSTOM); Sprintln("with rate "); } Sprintln("presented."); } if (interruptPresent) { wait(sendPause); present(chanInterrupt, S_MOTION, "Motion", true); Sprintln("Interrupt sensor presented."); } wait(sendPause); } /**************************************************************************/ void loop(void) { if (wakeReason < 0) { Serial.println("Reading sensors..."); switch (sensorFunc) { case 0: break; case 1: updateRFM(); break; case 2: updateDS18(); break; case 3: updateHTU(); break; case 4: if (sendLoop <= 0) { updateBME(); updated = true; } else { Sprint("\nTrend: "); updateTrend(); sendLoop--; } break; } if (lightPresent) { updateMAX(); if (sensorFunc <= 3) { Sprint("\nTrend: "); updateTrend(); } } wakeReason = 0; Sprintln("\nSensors updated..."); } else if (wakeReason == 1) { updateInterrupt(); wakeReason = 0; } if (battStatCounter >= battUpdater) { batteryStats(); } if (updated) { sendLoop = SENSOR_UPDATE; updated = false; } if (millis() >= currTime + sleepWait) { startUp = false; sleepSensor(); } } /**************************************************************************/ void updateInterrupt() {/* Sprintln("\nInterrupt: "); interruptState = reedContact.read(); wait(50); if (interruptState == !lastInterrupt) { send(msgIntr.setSensor(chanInterrupt).set(interruptState),true); lastInterrupt = interruptState; } Sprint("Door/window is "); if (interruptState) { Sprintln("opened."); } else { Sprintln("closed"); }*/ } /**************************************************************************/ void updateRFM() {/* Sprintln("\nRFM: "); sensorData = wireless.readTemperature(); wait(20); send(msgTemp.set(sensorData, 0)); Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent."); battStatCounter++;*/ } /**************************************************************************/ void updateDS18() {/* Sprintln("\nOne-wire: "); DS18.requestTemperatures(); sensorData = DS18.getTempCByIndex(0); wait(20); send(msgTemp.set(sensorData, 2)); battStatCounter++; Sprint("Temperature: "); Sprint(sensorData); Sprintln(" sent.");*/ } /**************************************************************************/ void updateHTU() { Sprintln("\nHTU: "); sensorData = HTU.readTemperature(); heatTemp = sensorData; wait(20); send(msgTemp.set(sensorData, 1)); Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent."); sensorData = HTU.readHumidity(); heatHum = sensorData; wait(sendPause); send(msgHum.set(sensorData, 1)); Sprint("Humidity: \t"); Sprint(sensorData); Sprintln(" sent."); //wait(sendPause); //send(msgHeat.set(computeHeatIndex(heatTemp, heatHum), 1)); //Sprint("Heatindex sent."); battStatCounter++; } /**************************************************************************/ void updateBME() { /*Sprintln("\nBME: "); BME.begin(); wait(100); sensorData = (BME.readFloatPressure()/pow(1-(alti/44330.0),5.255)/100); if (!startUp) { trend(sensorData); send(msgBaro.set(sensorData,1)); Sprint("Pressure: \t"); Sprint(sensorData); Sprintln(" sent."); } if (!(minuteCount < 35 && firstRound)) { wait(sendPause); send(msgTrend.set(dP_dt,2)); Sprint("Trend: \t\t"); Sprint(dP_dt); Sprintln(" sent."); } wait(sendPause); sensorData = BME.readTempC(); heatTemp = sensorData; send(msgTemp.set(sensorData,1)); Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent."); wait(sendPause); sensorData = BME.readFloatHumidity(); heatHum = sensorData; send(msgHum.set(sensorData,1)); Sprint("Humidity: \t"); Sprint(sensorData); Sprintln(" sent."); wait(sendPause); send(msgHeat.set(computeHeatIndex(heatTemp, heatHum), 1)); Sprint("Heatindex sent."); battStatCounter++;*/ } /**************************************************************************/ float computeHeatIndex(float tempInput, float humInput) //Function derived from Adafruit DHT library { /*// Using both Rothfusz and Steadman's equations // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml float hiFar; float tempFar = tempInput * 1.8 + 32; hiFar = 0.5 * (tempFar + 61.0 + ((tempFar - 68.0) * 1.2) + (humInput * 0.094)); if (hiFar > 79) { hiFar = -42.379 + 2.04901523 * tempFar + 10.14333127 * humInput + -0.22475541 * tempFar*humInput + -0.00683783 * pow(tempFar, 2) + -0.05481717 * pow(humInput, 2) + 0.00122874 * pow(tempFar, 2) * humInput + 0.00085282 * tempFar*pow(humInput, 2) + -0.00000199 * pow(tempFar, 2) * pow(humInput, 2); if((humInput < 13) && (tempFar >= 80.0) && (tempFar <= 112.0)) hiFar -= ((13.0 - humInput) * 0.25) * sqrt((17.0 - abs(tempFar - 95.0)) * 0.05882); else if((humInput > 85.0) && (tempFar >= 80.0) && (tempFar <= 87.0)) hiFar += ((humInput - 85.0) * 0.1) * ((87.0 - tempFar) * 0.2); } return (hiFar - 32) * 0.55555;*/ } /**************************************************************************/ void updateTrend() { /*if (sensorFunc == 4) { * Sprint("BME -> "); BME.begin(); wait(100); sensorData = (BME.readFloatPressure()/pow(1-(alti/44330.0),5.255)/100); } else if (lightPresent) { Sprint("MAX -> "); sensorData = lightMax.getLux(); } trend(sensorData);*/ } /**************************************************************************/ void updateMAX() { /*Sprintln("\nLight: "); sensorData = lightMax.getLux(); if (sensorFunc <= 3) { trend(sensorData); } send(msgLight.set(sensorData,1)); Sprint("Light: \t"); Sprint(sensorData); Sprintln(" sent."); if (sensorFunc <= 3) { if (!(minuteCount < 35 && firstRound)) { wait(sendPause); send(msgTrend.set(dP_dt,2)); Sprint("Trend: \t"); Sprint(dP_dt); Sprintln(" sent."); } } battStatCounter++;*/ } /**************************************************************************/ void sleepSensor() { if (battPower) { Serial.println("\nSleep the sensor."); wait(50); unsigned long lightsOut = (sleepTime - (millis() - currTime)); if (interruptPresent) { if (sensorPresent) { wakeReason = sleep(1, CHANGE, lightsOut); } else { wakeReason = sleep(1, CHANGE, 0); } } else { //digitalWrite(sensorPowerPin, LOW); //Disabled because of the I2C pull ups on the HTU board sleep(lightsOut); //causing a 140uA load in sleep. Without, sleep drain is 5uA. wakeReason = -1; //digitalWrite(sensorPowerPin, HIGH); wait(50); } currTime = millis(); Sprint("Wake reason: ");Sprintln(wakeReason); } else if (millis() >= currTime + sleepTime) { wakeReason = -1; currTime = millis(); } } /**************************************************************************/ /*void startBME() { BME.settings.commInterface = I2C_MODE; BME.settings.I2CAddress = BMEaddr; BME.settings.runMode = 1; // 1, Single mode BME.settings.tStandby = 0; // 0, 0.5ms BME.settings.filter = 0; // 0, filter off BME.settings.tempOverSample = 1; BME.settings.pressOverSample = 1; BME.settings.humidOverSample = 1; BME.begin(); } /**************************************************************************/ float getLastPressureSamplesAverage() { float lastPressureSamplesAverage = 0; for (int i = 0; i < LAST_SAMPLES_COUNT; i++) { lastPressureSamplesAverage += lastPressureSamples[i]; } lastPressureSamplesAverage /= LAST_SAMPLES_COUNT; return lastPressureSamplesAverage; } /**************************************************************************/ void trend(float pressure) {/* int index = minuteCount % LAST_SAMPLES_COUNT; // Calculate the average of the last 5 minutes. lastPressureSamples[index] = pressure; minuteCount++; if (minuteCount > 185) { minuteCount = 6; } if (minuteCount == 5) { pressureAvg = getLastPressureSamplesAverage(); Sprint("First average: "); Sprint(pressureAvg); } else if (minuteCount == 35) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change * 2; // note this is for t = 0.5hour } else { dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value. } } else if (minuteCount == 65) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) //first time initial 3 hour { dP_dt = change; //note this is for t = 1 hour } else { dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value } } else if (minuteCount == 95) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change / 1.5; // note this is for t = 1.5 hour } else { dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value } } else if (minuteCount == 125) { float lastPressureAvg = getLastPressureSamplesAverage(); pressureAvg2 = lastPressureAvg; // store for later use. float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change / 2; // note this is for t = 2 hour } else { dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value } } else if (minuteCount == 155) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change / 2.5; // note this is for t = 2.5 hour } else { dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value } } else if (minuteCount == 185) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change / 3; // note this is for t = 3 hour } else { dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value } pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past. firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop. } Sprint(F("\tForecast at minute ")); Sprint(minuteCount); Sprint(F(" dP/dt = ")); Sprint(dP_dt); Sprint(F("hPa/h --> "));*/ } /**************************************************************************/ void batteryStats() { if (battPower) { float battPct = vcc.Read_Perc(); float battVolt = vcc.Read_Volts(); wait(50); sendBatteryLevel(battPct); Sprint("Battery level: "); Sprint(battVolt); Sprintln("V.\n"); battStatCounter = 0; wait(50); } } /**************************************************************************/ void sendBattLevel() { /*Serial.println("\nBattery: "); int ADread = analogRead(batteryPin); int battPcnt = map(ADread, 570, 704, 0, 100); //Usable voltage range from 3.4 to 4.2V battPcnt = constrain(battPcnt, 0, 100); //Charging keeps it at 100% sendBatteryLevel(battPcnt); Sprint("\nADread\t"); Sprint(ADread); Sprint("\t"); Sprintln(battPcnt); battStatCounter = 0;*/ }GertSanders ATMega328p 32p TFQP, 8MHz, 38400baud
Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB Sketch uses 16,680 bytes (51%) of program storage space. Maximum is 32,256 bytes. Global variables use 942 bytes (45%) of dynamic memory, leaving 1,106 bytes for local variables. Maximum is 2,048 bytes.LowPowerLab Moteino 16MHz
Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB Sketch uses 14,264 bytes (44%) of program storage space. Maximum is 31,744 bytes. Global variables use 890 bytes of dynamic memory.In this sketch the size difference doesn't matter that much. But when I introduce signing it will get tight.
Any thoughts?(This is a standard sketch which I adapt for every node by commenting out the parts I do not need. So it might seem large for a simple temperature node. It is...).
-
I have been running your bootloader for all my nodes now and that works very well.
But there is something that surprised me. When I compile the next sketch and compare that with the Moteino bootloader it's substantially larger./*************************************************************************************** ** ** Outdoor sensor v1.0 Measuring temperature, humdity, pressure and light level ** Calculating a weather forecast with the height comensated air pressure. ** powered by a solar panel and a 1000mAh Li-Ion battery. ** ** Scraped together by D Hille. MySensors library by Henrik Ekblad et al. ** ** Heat index calculation from DHT library by Adafruit ** MAX44009 bij Rob Tillaart ** Weather forecast based on AN3914 by Freescale ** ****************************************************************************************/ // MySensors definitions //#define MY_DEBUG // Enable debug prints (6 kb flash space) //#define MY_DEBUG_VERBOSE_SIGNING // Comment out when no signing is used or when everything is OK (3 kb flash space) #define MY_BAUD_RATE 57600 // Set serial baudrate #define MY_RADIO_RFM69 // Enable and select radio type attached //#define MY_IS_RFM69HW // Comment out when using standard RFM69W #define MY_NODE_ID 110 // Delete to use automatic ID assignment //#define MY_CORE_ONLY /**************************************************************************/ // Transport /**************************************************************************/ //#define MY_TRANSPORT_WAIT_READY_MS 1000 //Start the node even if no connection to the GW could be made (disable for sensor nodes). #define MY_TRANSPORT_STATE_RETRIES 1 #define MY_TRANSPORT_MAX_TSM_FAILURES (2u) #define MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE (60*1000ul) /**************************************************************************/ // Security /**************************************************************************/ //#define MY_SIGNING_ATSHA204 //#define MY_SIGNING_SOFT //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //#define MY_SIGNING_REQUEST_SIGNATURES //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = 0,.serial = {0xD0,0xB1,0x90,0x99,0xC3,0x03,0x08,0xD1,0x34}}} //#define MY_RFM69_ENABLE_ENCRYPTION /**************************************************************************/ // Sensor definitions /**************************************************************************/ #define BATTERY_POWERED #define battUpdater 300 //Number of TX actions to count before a new battery status update is sent. #define MY_DEFAULT_TX_LED_PIN 5 // Comment out when no LED is attached. #define MY_WITH_LEDS_BLINKING_INVERSE #define SENSOR_TYPE 3 // Sensor types: // 0.: no climate sensor attached // 1.: RFM69 on-die Temperature sensor on the RFM69 module (whole integers only) // 2.: DS18B20 Dallas one-wire sensor(data pin D14) // 3.: HTU21D Temp/humidity (I2C) // 4.: BME280 Temp/humidity/pressure (I2C) (node will wake every minute to keep up with trend measureing) #define SENSOR_UPDATE 2 // Time in minutes the sensor sends an update //#define LIGHT_SENSOR_PRESENT // Comment out when not present. (I2C) (Light sensor will update every 60 seconds.) //#define INTERRUPT_SENSOR_PRESENT // Comment out when not present (e. g. motion sensor connect to D3) #define alti 57 //altitude offset to compensate the barometric pressure /**************************************************************************/ // Debug definitions /**************************************************************************/ //#define LOCAL_DEBUG //Comment out to switch all debug messages off (saves 2 kb flash) #ifdef MY_DEBUG //Differentiate between global debug including radio and local debug #define LOCAL_DEBUG //for the sketch alone. #endif #ifdef LOCAL_DEBUG #define Sprint(a) (Serial.print(a)) // Macro as substitute for serial debug. Will be an empty macro when #define Sprintln(a) (Serial.println(a)) // debug is switched off #else #define Sprint(a) #define Sprintln(a) #endif /**************************************************************************/ #include <Button.h> #include <SPI.h> #include <Wire.h> #include <MySensors.h> //#include <SparkFunBME280.h> //#include <MAX44009.h> // Uncomment library used in sketch #include <Adafruit_HTU21DF.h> //#include <OneWire.h> //#include <DallasTemperature.h> #include <Vcc.h> #define BMEaddr 0x76 #define Max44099Addr 0x4A #define sketchName "sensorNode(living)" #define sketchVer "1.0" #define sensorPowerPin 20 #define digitalSensorPin 14 #define analogSensorPin A0 #define oneWireBusPin 14 #define interruptPin 3 #define altSensorPin 18 #define altAnalogPin A4 #define sensorPowerPin 6 #define chanTemp 0 #define chanHum 1 #define chanHeat 2 #define chanBaro 3 #define chanDelta 4 #define chanLight 5 #define chanRate 6 #define chanInterrupt 8 #define PULLUP false #define INVERT false #define bounceTime 20 #define sleepWait 500 //Time to wait in ms before node sleeps (to be able to receive notification messages). bool battPower = true; unsigned long currTime = 0; unsigned long sleepTime = (60000 * SENSOR_UPDATE); unsigned long lastSensorUpdate; unsigned long nextSensor; unsigned long measureTime; int wakeReason = -1; int sendLoop = 0; bool updated = false; bool ACKed = false; int sensorFunc = 0; float sensorData = 0.0; float heatTemp = 0.0; float heatHum = 0.0; bool interruptState = false; bool lastInterrupt = false; bool sensorPresent = false; bool lightPresent = false; bool interruptPresent = false; int minuteCount = 0; bool firstRound = true; float pressureAvg; // average value is used in forecast algorithm. float pressureAvg2; // average after 2 hours is used as reference value for the next iteration. float dP_dt; const int LAST_SAMPLES_COUNT = 5; float lastPressureSamples[LAST_SAMPLES_COUNT]; bool startUp = true; bool metric = true; int battStatCounter = 0; const float VccMin = 1.8; // Minimum expected Vcc level, in Volts. const float VccMax = 3.0; // Maximum expected Vcc level, in Volts. const float VccCorrection = 1.0/1.0; // Measured Vcc by multimeter divided by reported Vcc /**************************************************************************/ // Library declarations /**************************************************************************/ // Uncomment necessary declarations. //RFM69 wireless; //OneWire OWB(oneWireBusPin); //DallasTemperature DS18(&OWB); //DeviceAddress DS18address; Adafruit_HTU21DF HTU = Adafruit_HTU21DF(); //BME280 BME; //Max44009 lightMax(Max44099Addr); //Button reedContact(interruptPin, PULLUP, INVERT, bounceTime); MyMessage msgHum(chanHum, V_HUM); MyMessage msgTemp(chanTemp, V_TEMP); //MyMessage msgBaro(chanBaro, V_PRESSURE); //MyMessage msgTrend(chanUniversal, V_VAR5); //MyMessage msgLight(chanLight, V_LEVEL); //MyMessage msgIntr(chanInterrupt, V_TRIPPED); Vcc vcc(VccCorrection); /**************************************************************************/ // Error messages /**************************************************************************/ #if (defined INTERRUPT_SENSOR_PRESENT && defined LIGHT_SENSOR_PRESENT && SENSOR_TYPE >= 4) #error Motion sensor can anly be combined with either I2C OR one-wire sensors, not both. #endif #if (defined INTERRUPT_SENSOR_PRESENT && (defined LIGHT_SENSOR_PRESENT || SENSOR_TYPE == 4) && defined BATTERY_POWERED) #error Interrupt sensor is not compatible with trend sensors like 'baro' and 'light' because the timer will misalign. #endif #if (SENSOR_TYPE > 4) #error Not a valid sensor type! #endif /**************************************************************************/ void before(void) { Serial.println("\nReading config..."); #ifndef BATTERY_POWERED battPower = false; #endif sensorFunc = SENSOR_TYPE; #ifdef LIGHT_SENSOR_PRESENT lightPresent = true; #endif #ifdef INTERRUPT_SENSOR_PRESENT interruptPresent = true; lastInterrupt = reedContact.read(); #endif #if (defined MY_SIGNING_SOFT || defined MY_SIGNING_ATSHA204) #define sendPause 100 #else #define sendPause 50 #endif } /**************************************************************************/ void setup(void) { pinMode(sensorPowerPin, OUTPUT); //switch on the sensor power digitalWrite(sensorPowerPin, HIGH); wait(50); //wait 50 ms for the sensors to settle. switch (sensorFunc) { case 0: break; case 1: sensorPresent = true; break; case 2: //DS18.begin(); //DS18.getAddress(DS18address, 0); //DS18.setResolution(DS18address, 10); sensorPresent = true; break; case 3: HTU.begin(); sensorPresent = true; break; case 4: //startBME(); sleepTime = 60000; sensorPresent = true; break; } #if (lightPresent) sleepTime = 60000; sensorPresent = true; #endif #ifdef MY_DEBUG //Differentiate between global debug including radio and local debug sleepTime = 30000; //for the sketch alone. #endif batteryStats(); Serial.println("\nDone. \n\nStarting program.\n"); currTime = millis(); } /**************************************************************************/ void presentation() { Serial.println("Start radio and sensors"); sendSketchInfo(sketchName, sketchVer); Sprint("\nPresent "); if (sensorFunc >= 1) { wait(sendPause); present(chanTemp, S_TEMP, "Climate", true); Sprint("temperature"); } if (sensorFunc >= 3) { wait(sendPause); present(chanHum, S_HUM); Sprint(", humidity"); //wait(sendPause); //present(chanHeat ,S_TEMP); //Sprint(", heatindex"); } if (sensorFunc == 4) { wait(sendPause); present(chanBaro, S_BARO); Sprint(", barometric"); wait(sendPause); present(chanDelta, S_CUSTOM); Sprint(" and rate"); } Sprintln(" sensor."); if (lightPresent) { wait(sendPause); present(chanLight, S_LIGHT_LEVEL, "Light", true); Sprintln("\nLightsensor "); if (sensorFunc < 4) { wait(sendPause); present(chanRate, S_CUSTOM); Sprintln("with rate "); } Sprintln("presented."); } if (interruptPresent) { wait(sendPause); present(chanInterrupt, S_MOTION, "Motion", true); Sprintln("Interrupt sensor presented."); } wait(sendPause); } /**************************************************************************/ void loop(void) { if (wakeReason < 0) { Serial.println("Reading sensors..."); switch (sensorFunc) { case 0: break; case 1: updateRFM(); break; case 2: updateDS18(); break; case 3: updateHTU(); break; case 4: if (sendLoop <= 0) { updateBME(); updated = true; } else { Sprint("\nTrend: "); updateTrend(); sendLoop--; } break; } if (lightPresent) { updateMAX(); if (sensorFunc <= 3) { Sprint("\nTrend: "); updateTrend(); } } wakeReason = 0; Sprintln("\nSensors updated..."); } else if (wakeReason == 1) { updateInterrupt(); wakeReason = 0; } if (battStatCounter >= battUpdater) { batteryStats(); } if (updated) { sendLoop = SENSOR_UPDATE; updated = false; } if (millis() >= currTime + sleepWait) { startUp = false; sleepSensor(); } } /**************************************************************************/ void updateInterrupt() {/* Sprintln("\nInterrupt: "); interruptState = reedContact.read(); wait(50); if (interruptState == !lastInterrupt) { send(msgIntr.setSensor(chanInterrupt).set(interruptState),true); lastInterrupt = interruptState; } Sprint("Door/window is "); if (interruptState) { Sprintln("opened."); } else { Sprintln("closed"); }*/ } /**************************************************************************/ void updateRFM() {/* Sprintln("\nRFM: "); sensorData = wireless.readTemperature(); wait(20); send(msgTemp.set(sensorData, 0)); Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent."); battStatCounter++;*/ } /**************************************************************************/ void updateDS18() {/* Sprintln("\nOne-wire: "); DS18.requestTemperatures(); sensorData = DS18.getTempCByIndex(0); wait(20); send(msgTemp.set(sensorData, 2)); battStatCounter++; Sprint("Temperature: "); Sprint(sensorData); Sprintln(" sent.");*/ } /**************************************************************************/ void updateHTU() { Sprintln("\nHTU: "); sensorData = HTU.readTemperature(); heatTemp = sensorData; wait(20); send(msgTemp.set(sensorData, 1)); Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent."); sensorData = HTU.readHumidity(); heatHum = sensorData; wait(sendPause); send(msgHum.set(sensorData, 1)); Sprint("Humidity: \t"); Sprint(sensorData); Sprintln(" sent."); //wait(sendPause); //send(msgHeat.set(computeHeatIndex(heatTemp, heatHum), 1)); //Sprint("Heatindex sent."); battStatCounter++; } /**************************************************************************/ void updateBME() { /*Sprintln("\nBME: "); BME.begin(); wait(100); sensorData = (BME.readFloatPressure()/pow(1-(alti/44330.0),5.255)/100); if (!startUp) { trend(sensorData); send(msgBaro.set(sensorData,1)); Sprint("Pressure: \t"); Sprint(sensorData); Sprintln(" sent."); } if (!(minuteCount < 35 && firstRound)) { wait(sendPause); send(msgTrend.set(dP_dt,2)); Sprint("Trend: \t\t"); Sprint(dP_dt); Sprintln(" sent."); } wait(sendPause); sensorData = BME.readTempC(); heatTemp = sensorData; send(msgTemp.set(sensorData,1)); Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent."); wait(sendPause); sensorData = BME.readFloatHumidity(); heatHum = sensorData; send(msgHum.set(sensorData,1)); Sprint("Humidity: \t"); Sprint(sensorData); Sprintln(" sent."); wait(sendPause); send(msgHeat.set(computeHeatIndex(heatTemp, heatHum), 1)); Sprint("Heatindex sent."); battStatCounter++;*/ } /**************************************************************************/ float computeHeatIndex(float tempInput, float humInput) //Function derived from Adafruit DHT library { /*// Using both Rothfusz and Steadman's equations // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml float hiFar; float tempFar = tempInput * 1.8 + 32; hiFar = 0.5 * (tempFar + 61.0 + ((tempFar - 68.0) * 1.2) + (humInput * 0.094)); if (hiFar > 79) { hiFar = -42.379 + 2.04901523 * tempFar + 10.14333127 * humInput + -0.22475541 * tempFar*humInput + -0.00683783 * pow(tempFar, 2) + -0.05481717 * pow(humInput, 2) + 0.00122874 * pow(tempFar, 2) * humInput + 0.00085282 * tempFar*pow(humInput, 2) + -0.00000199 * pow(tempFar, 2) * pow(humInput, 2); if((humInput < 13) && (tempFar >= 80.0) && (tempFar <= 112.0)) hiFar -= ((13.0 - humInput) * 0.25) * sqrt((17.0 - abs(tempFar - 95.0)) * 0.05882); else if((humInput > 85.0) && (tempFar >= 80.0) && (tempFar <= 87.0)) hiFar += ((humInput - 85.0) * 0.1) * ((87.0 - tempFar) * 0.2); } return (hiFar - 32) * 0.55555;*/ } /**************************************************************************/ void updateTrend() { /*if (sensorFunc == 4) { * Sprint("BME -> "); BME.begin(); wait(100); sensorData = (BME.readFloatPressure()/pow(1-(alti/44330.0),5.255)/100); } else if (lightPresent) { Sprint("MAX -> "); sensorData = lightMax.getLux(); } trend(sensorData);*/ } /**************************************************************************/ void updateMAX() { /*Sprintln("\nLight: "); sensorData = lightMax.getLux(); if (sensorFunc <= 3) { trend(sensorData); } send(msgLight.set(sensorData,1)); Sprint("Light: \t"); Sprint(sensorData); Sprintln(" sent."); if (sensorFunc <= 3) { if (!(minuteCount < 35 && firstRound)) { wait(sendPause); send(msgTrend.set(dP_dt,2)); Sprint("Trend: \t"); Sprint(dP_dt); Sprintln(" sent."); } } battStatCounter++;*/ } /**************************************************************************/ void sleepSensor() { if (battPower) { Serial.println("\nSleep the sensor."); wait(50); unsigned long lightsOut = (sleepTime - (millis() - currTime)); if (interruptPresent) { if (sensorPresent) { wakeReason = sleep(1, CHANGE, lightsOut); } else { wakeReason = sleep(1, CHANGE, 0); } } else { //digitalWrite(sensorPowerPin, LOW); //Disabled because of the I2C pull ups on the HTU board sleep(lightsOut); //causing a 140uA load in sleep. Without, sleep drain is 5uA. wakeReason = -1; //digitalWrite(sensorPowerPin, HIGH); wait(50); } currTime = millis(); Sprint("Wake reason: ");Sprintln(wakeReason); } else if (millis() >= currTime + sleepTime) { wakeReason = -1; currTime = millis(); } } /**************************************************************************/ /*void startBME() { BME.settings.commInterface = I2C_MODE; BME.settings.I2CAddress = BMEaddr; BME.settings.runMode = 1; // 1, Single mode BME.settings.tStandby = 0; // 0, 0.5ms BME.settings.filter = 0; // 0, filter off BME.settings.tempOverSample = 1; BME.settings.pressOverSample = 1; BME.settings.humidOverSample = 1; BME.begin(); } /**************************************************************************/ float getLastPressureSamplesAverage() { float lastPressureSamplesAverage = 0; for (int i = 0; i < LAST_SAMPLES_COUNT; i++) { lastPressureSamplesAverage += lastPressureSamples[i]; } lastPressureSamplesAverage /= LAST_SAMPLES_COUNT; return lastPressureSamplesAverage; } /**************************************************************************/ void trend(float pressure) {/* int index = minuteCount % LAST_SAMPLES_COUNT; // Calculate the average of the last 5 minutes. lastPressureSamples[index] = pressure; minuteCount++; if (minuteCount > 185) { minuteCount = 6; } if (minuteCount == 5) { pressureAvg = getLastPressureSamplesAverage(); Sprint("First average: "); Sprint(pressureAvg); } else if (minuteCount == 35) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change * 2; // note this is for t = 0.5hour } else { dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value. } } else if (minuteCount == 65) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) //first time initial 3 hour { dP_dt = change; //note this is for t = 1 hour } else { dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value } } else if (minuteCount == 95) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change / 1.5; // note this is for t = 1.5 hour } else { dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value } } else if (minuteCount == 125) { float lastPressureAvg = getLastPressureSamplesAverage(); pressureAvg2 = lastPressureAvg; // store for later use. float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change / 2; // note this is for t = 2 hour } else { dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value } } else if (minuteCount == 155) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change / 2.5; // note this is for t = 2.5 hour } else { dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value } } else if (minuteCount == 185) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg); if (firstRound) // first time initial 3 hour { dP_dt = change / 3; // note this is for t = 3 hour } else { dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value } pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past. firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop. } Sprint(F("\tForecast at minute ")); Sprint(minuteCount); Sprint(F(" dP/dt = ")); Sprint(dP_dt); Sprint(F("hPa/h --> "));*/ } /**************************************************************************/ void batteryStats() { if (battPower) { float battPct = vcc.Read_Perc(); float battVolt = vcc.Read_Volts(); wait(50); sendBatteryLevel(battPct); Sprint("Battery level: "); Sprint(battVolt); Sprintln("V.\n"); battStatCounter = 0; wait(50); } } /**************************************************************************/ void sendBattLevel() { /*Serial.println("\nBattery: "); int ADread = analogRead(batteryPin); int battPcnt = map(ADread, 570, 704, 0, 100); //Usable voltage range from 3.4 to 4.2V battPcnt = constrain(battPcnt, 0, 100); //Charging keeps it at 100% sendBatteryLevel(battPcnt); Sprint("\nADread\t"); Sprint(ADread); Sprint("\t"); Sprintln(battPcnt); battStatCounter = 0;*/ }GertSanders ATMega328p 32p TFQP, 8MHz, 38400baud
Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB Sketch uses 16,680 bytes (51%) of program storage space. Maximum is 32,256 bytes. Global variables use 942 bytes (45%) of dynamic memory, leaving 1,106 bytes for local variables. Maximum is 2,048 bytes.LowPowerLab Moteino 16MHz
Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB Sketch uses 14,264 bytes (44%) of program storage space. Maximum is 31,744 bytes. Global variables use 890 bytes of dynamic memory.In this sketch the size difference doesn't matter that much. But when I introduce signing it will get tight.
Any thoughts?(This is a standard sketch which I adapt for every node by commenting out the parts I do not need. So it might seem large for a simple temperature node. It is...).
@DavidZH
Do you also get these differences when compiling for both 16Mhz ? In this case one node is 16MHz (Moteino) and the second is 8MHz.
Apart from that I have no clue why this would result in different sizes. -
I have tried with your bootloader on 16MHz and 8 MHz with crystal.
8MHz, crystal, 1V8
Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB Build options changed, rebuilding all Sketch uses 16,680 bytes (51%) of program storage space. Maximum is 32,256 bytes. Global variables use 942 bytes (45%) of dynamic memory, leaving 1,106 bytes for local variables. Maximum is 2,048 bytes.16MHz, crystal, 1V8
Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB Build options changed, rebuilding all Sketch uses 16,694 bytes (51%) of program storage space. Maximum is 32,256 bytes. Global variables use 942 bytes (45%) of dynamic memory, leaving 1,106 bytes for local variables. Maximum is 2,048 bytes.So the 16Mhz file is actally even a bit bigger. I also tried if changing the BOD voltage would change anything, but nope on that.
Might be something to look into in a spare hour.
-
@mar.conte - Your question isn't very clear. If you're asking what the name means its broken down as:
8mhz - Crystal speed/frequency
38k4 - 38400 upload speed
D13 - Pin 13 to flash the LED (if needed) just for visual indication that the bootloader has been burnt/installed.Not sure if that is what you meant but I could only assume. If not then please attempt to explain a little clearly for us :)
Hope that sorts your problem!
-
@mar.conte - Your question isn't very clear. If you're asking what the name means its broken down as:
8mhz - Crystal speed/frequency
38k4 - 38400 upload speed
D13 - Pin 13 to flash the LED (if needed) just for visual indication that the bootloader has been burnt/installed.Not sure if that is what you meant but I could only assume. If not then please attempt to explain a little clearly for us :)
Hope that sorts your problem!
@Samuel235
Sorry for my english, your answer is ok Tanks you -
@Samuel235
Sorry for my english, your answer is ok Tanks you@mar.conte - Its okay, i understood you, just about ;)
Now just apply that description to all of the other bootloader varients that the great @Gertsanders has provided us with :)
-
I'm sorry, i don't understand the issue at hand.... Could you attempt to explain any clearer?