-
I think I have another issue which is available flash space. Currently I have
FlashEEPROM start_address = 393216
Flash start_address = 397312, end_address = 430080But process.memory().flash_code_start is reported as 442368. So I only have 12kb of space left which is not going to be enough for storing 2 copies of code. So I may have to rethink my strategy a bit if I cant get a little more free flash space.
Is there a way to alter .flash_code_start ? As the only initially saved() code would be my small bootloader
-
On the MDBT42 currently I use Flash (for a circular logging buffer where some bytes are written twice before erase) and FlashEEPROM for storing a couple of params. I make sure they don't overlap by doing the following:
flashEEPROM = new (require("FlashEEPROM"))(); flashEEPROM.endAddr = flashEEPROM.addr+PAGE_SIZE; flash = require("Flash"); logStartAddress = flashEEPROM.endAddr; logEndAddress = logStartAddress + NUM_LOG_PAGES*PAGE_SIZE;
I am interested in swapping out flashEEPROM for the new Storage Library as want to store downloaded code to run and it seems a nice way to handle it. Can I get it to run alongside the Flash library ? If not I will just use the Flash lib to store the code.
-
-
-
I have attached a SI7055 temperature sensor to a Ruuvitag as I need 2x temperature sensors for an application. My simple test app is below . If I call readBmpTemp() I get a correct temperature. If I then call read7055Temp() - the first time I get an I2C arbitration error and then the second call works. If I switch back to readBmpTemp() the first reading is incorrect etc
Is there something I have setup wrong ?
var i2c; var Ruuvitag; function onInit() { Ruuvitag = require("Ruuvitag"); Ruuvitag.setEnvOn(true); i2c = new I2C(); i2c.setup({ scl : D28, sda: D29 }); } function read7055Temp() { i2c.writeTo(0x40, [0xf3,0x40,0x40,0x40]); setTimeout(function() { var rawTemp = i2c.readFrom(0x40, 2); var val = (rawTemp[0] << 8) + rawTemp[1]; var temp = (175.72*val) / 65536 - 46.85; console.log(temp); }, 10); } function readBmpTemp() { console.log(Ruuvitag.getEnvData()); }
-
-
-
-
I am using the native IDE, as that is the only one I find I can connect successfully to the MDBT42 module with on Windows. However the minify options are not on the settings page - how do I get that option ?
I need to get the minify working as I am now getting ERROR: Too big to save to flash (13812 vs 12284 bytes) - although I do have 957 memory blocks still free
I also get New interpreter error: MEMORY_BUSY, not sure if that is an issue also ?
-
-
A 0.1 pitch board could be useful, depends how we end up making it. What is involved in getting Espruino onto a MDBT42Q module? If we go that way we could always become a Patreon to get ongoing support?
I did not use the extra flash page on the Pico as I was saving for saving remote code updates. If it was broken into several pages it would have been ideal.
-
I could be interested in a nRF52 board with Espruino preloaded.
Our current wireless logging solution is made up of two devices. The first is a battery powered Arduino that broadcasts two temperatures regularly, using a nrf24L01. The second device has a Pico/SIM800/nrf24L01/LCD/EEPROM.
I am thinking that it could be a nicer solution to have both devices nrf52 based as the BLE comms would be useful for some additional features we wish to add. My main unknown is whether all the software will fit/run in the nrf52 ? The current software runs with 800 blocks free mem on the Pico, using standard Save and no Pretokenise.
Does Espruino support using the nrf52 flash for writing general logging data ? I know that its endurance is only 10000 writes but there is lots of it so that should not be an issue for me.
-
My only concern around not having the V1 code in there as a fallback, is that if the V2 download fails and the unit reboots, it is then a non-functional unit until it can successfully download code.
For our 24x7 remote logging application - this is not really an acceptable possibility.
So either I need a way of removing all the V1 code from RAM before running V2, or could I as part of the download new code process do this ?
- erasePage()
- write a dump of the current running code into Flash
- then follow by writing the V2 code (downloaded) into Flash
- If V2 downloads and verifies I can write to my EEPROM that the V2 code is valid to run - so the bootloader knows which version to load.
There would still be some risks around this, but probably acceptable for our application
- erasePage()
-
Am only just getting on to implementing this now !
So if I have say V1 of my code save() into the Pico (along with the above bootloader code in onInit() ?)
What is the best way for me to grab the correct V2 minified code that I would put on my server for the pico to download and write into flash (which would be run thru eval) ?
In the fallback scenario - When the new code is run via eval, I assume the existing V1 code would have already loaded at that point ? Do I need to get rid of it from RAM first somehow ?
Thanks
-
Its interesting, now I know it is a monthly issue, I can see strange things happening to our units on a monthly basis - although I cant exactly explain what is going on ie I would expect my software to crash completely, there definitely seems to be a correlation.
We need to put some more units out into the field in a few days or so time. Which build would you recommend we put on (given we don't have a months testing time) - the custom one you created or a travis build ?
-
Unfortunately I have no logs of getTime(). However on my debug unit, where the IDE 'Set current time' option was turned on - it crashed after 10 days on 31/07/2017 at 5:18pm (NZ time)
In my application, I resync the time to the SIM800 time (new Clock object) every 90s. So it is possible that my app would only crash if the clock step back happened when my code was actually doing something that relies on getTime() before the next SIM800 re-sync.
-
Interestingly I just checked my IDE settings and I do have the 'Set current time' option turned on.
So that makes the Sun Jan 30 2000 15:24:42 time that was in the unit after crash seem not right ? As I am pretty sure the unit was never powered down after the last software was loaded onto the pico.
I had loaded the new software 10 days earlier in this case.
-
Great thanks for that. I will run this on some units to see if it makes a difference - might take a while to determine if there is a difference compared to standard firmware. I will also try to add some logging to capture the RTC time if I can detect it happens again.
I do use deepsleep, but only when the power is disconnected, which should not have been the case. When in deepsleep it will be waking up every 4s, so not asleep long.
-
Yep, pretty strange.
- No I never use setTime() as I was worried about causing an issue like this :)
- I have observed on 1.87 and 1.92
- Unfortunately I don't know what the getTime() value was at the time of the crash as I was not logging that to the console. Working backwards it would have been around 949245868 at restart time after the crash.
To keep absolute time, my code regularly queries the local time from the SIM800, then each time I instantiate a new Clock object. This then keeps things accurate for Pico we have not yet put on the crystal.
The clock speeding up would explain why my EEPROM read failed at that time also. In my code I do a EEPROM write and then immediately follow with a read to verify. In the AT25 code there is a loop using getTime() to wait for the EEPROM write period. So if this is essentially skipped then the read would fail.
We never generally set the clock (using setTime) so in all our units it would be pretty random - unless it gets set by the IDE at programming time ?
- No I never use setTime() as I was worried about causing an issue like this :)
-
I have a number of Pico based units running 24x7 out in the field and have observed a few times in the last few months the RTC suddenly seeming to speed up.
I finally managed to catch this while logging the serial console on a unit - the sequence was:
- first sign of issues was the read process (a write verify) from the SPI EEPROM failed (read all zeros or FF's)
- Because the clock was going too fast, this was generating timing errors in my code, which I was logging (write to EEPROM - which did appear to work!)
- the Pico then started generating memory errors during SIM800 upload proess and restarted
- on restart the unit uploaded to my server the logged error events, which had advanced timestamps on them
- all the timestamps came from the standard espruino Clock module (based on getTime())
- the restart rectified the problem
The whole crash/restart process took around 30seconds (this is based on external timestamps coming from a SIM800), however my logged events (based on getClock()) over the 30second period went in a range of 18mins to 15hours into the future !??
This particular unit is running on LSI, but I am reasonably sure it has happened on a Pico we put on an external crystal (to be confirmed)
Is this even possible ??? It just seems that the RTC just suddenly started running around 1800x faster.
Any ideas appreciated - it would be nice to be able to detect and fix this rather than just crash.
- first sign of issues was the read process (a write verify) from the SPI EEPROM failed (read all zeros or FF's)
-
I have given my SIM900 module to Gordon so he can sync in the bug fixes I have made. There are a couple of other basic things required for reliable operation ie in netcallbacks/create - there are more unregisterLine required for error cases and you need to remove the CIPSTART exception throw. Also if the SIM800 CIPSTART fails, the driver wont catch that so I added a timeout which then closes the socket and things are cleaned up properly.
At the app level, you need to ensure that the connect/send/receive process is completely finished before calling again otherwise memory will be consumed - this also means catching errors so the process can unwind properly. Use the request.on('error', function(e) ...
If you are in a low coverage area and the SIM800 can falloff the network there are a whole lot more considerations that come into play - you could just choose the approach of if things go wrong, reset and start all over, but I chose to handle all the states the SIM800 can get into and handle them in a more managed fashion.
Hopefully Gordon will have the time to sync in the basics of my changes to benefit everyone.
-
My fix is for responses that are small in size - so you still need that.
If you are getting low memory errors you need to process your data in smaller chunks ie either optimise your json or request it in smaller chunks.
You never want to get into a low memory scenario as things start breaking pretty fast. It is worthwhile monitoring 'process.memory().free' at various parts of your code to highlight issues.
In my project - if I ever get an 'out of memory' error (which you should code to prevent) I reboot otherwise the code operation will be in an unknown state, also use the new watchdog feature.
-
This could be caused by a bug I found in the SIM900 driver. In the function 'receiverHandler' there is a line of code:
sockData[parms[0]] += line.substr(colon+1,parms[1]);This needs to be changed to
sockData[parms[0]] += line.substr(colon+3,parms[1]);I found if the whole response fitted within one handler transfer the orginal code would corrupt the response.
-
Hi Gordon, as you know I have made a bunch of changes to my own SIM900 module. Most of these changes you probably wont want in the standard library but there are a couple of important bug fixes here and there for the original code. There is one bug in the receiveHandler which can cause corruption depending on the data framing.
Shall I send you my current file so you can see my fixes ?
OK sounds good ! So the Storage lib is just using from flash_code_start onwards ? And so it wont clash with the Flash lib I have set to work between 397312 and 430080