I2C module 'hangs' on i2c error

  • Hi all

    I am trying to work with i2c and I need to 'scan' the bus for connected devices. If I do a simple write then read of something on the bus, everything works fine. However, if the address is for something not on the bus, I get a timeout as expected with the err being 'Error: Timeout during I2C transfer'. The problem is, if I try to do anything on the bus again the module 'hangs'. I have tried a simple write as well as first doing a .destroy and then a new.... but in both cases I get the same result. lowsync is not able to restart the program either. It can resync the files if I change them but cannot restart the program. It just times out. Only solution is to power cycle the module.

    Anyone else been able to get i2c working after an error?


  • After a bit more testing and tracing it is the .destroy() that seems to be breaking things.


    I see the first console.log but not the second. At this point the device seems to be hung. using lowsync --monitor=true times out while trying to restart the app


    (Ignore the path not found)

  • Hi!

    You say it hangs if you try to send to an address which does not exist and then destroy the I2C.
    Can you hack together a small program which hangs, even without any actual I2C connected? Someting like:

    send to address 1234
    console.log("THIS IS NOT SHOWN")

    If I have a index.js like that and reproduce things fast, I can fix the problem very very fast..



  • Here is a code snippet. Below it are the two outputs. addr = 99 is a valid one and 100 is not. You see it logs 'Destroying...' and then nothing.

    const i2cMod = require('i2c');
    const addr = 100;
    let con = new i2cMod.I2C({
    	pinSCL: 22,
    	pinSDA: 21
    const dataWrite = Buffer.alloc(1);
    dataWrite.writeUInt8(105, 0); // i for information
    con.transfer(addr, dataWrite, 0, (err, dataRead) => {
    	setTimeout(() => {
    		con.transfer(addr, null, 15, (err, dataRead) => {
    			if (err) {
    				console.log("Addr: 99 -- " + err);
    				setTimeout(() => {
    					console.log("Reinitializing i2c...");
    					con = new i2cMod.I2C({
    						pinSCL: 22,
    						pinSDA: 21
    				}, 1000);
    			} else {
    				const buf = dataRead.toJSON();
    				let str = '';
    				for (let i = 0; i < buf.data.length; i++) {
    					const char = buf.data[i];
    					if (char > 1)
    						str += String.fromCharCode(char);
    	}, 300);


  • The second one shows addr 99 as it is hard coded to 99 in the console.log. But the bottom one is with addr = 100. With nothing on the i2c bus, it will fail with any address.

  • OK, great. Looks easy enough. Hopefully I'll fix it fast. Latest on next weekend, if I do not get to it during the week. Thank you for your patience.

  • Ok fixed it in the new version 1.6.1, which you can flash now!

  • Excellent! Will pull it now and test. Thanks 👍

  • How do I check if the version on the module is upgraded? I re-flashed using lowsync flash --port=COM6 --init but the i2c issue still persists. Is there any way to see which version of low.js is currently installed on the module?

  • That command should flash the newest version. And your test program now works with that version (did not work with the version before). Just checked:

    Thomass-MBP:testtest t.rogg$ lowsync flash --port=/dev/tty.usbserial-14401 --init
    *** Step 1/3: Probing ESP32 microcontroller
        now checking if it is an ESP32-WROVER... (takes a while)
    *** Step 2/3: Erasing flash and building image in parallel
    esptool.py v2.6-beta1
    Serial port /dev/tty.usbserial-14401
    Detecting chip type... ESP32
    Chip is ESP32D0WDQ6 (revision 1)
    Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
    MAC: cc:50:e3:ab:5e:30
    Uploading stub...
    Running stub...
    Stub running...
    Erasing flash (this may take a while)...
    Downloading data from neonious servers...
    Building firmware...
    ****** Used flash space: ******
    low.js code       2097152 bytes
    low.js data        788760 bytes
    Static files            0 bytes
    Factory files        6812 bytes
    Modules             53830 bytes
    Settings              971 bytes
    Reserved           198203 bytes
    Total             3145728 bytes
    Chip erase completed successfully in 6.9s
    Hard resetting via RTS pin...
    *** Step 3/3: Flashing firmware
    esptool.py v2.6-beta1
    Serial port /dev/tty.usbserial-14401
    Detecting chip type... ESP32
    Chip is ESP32D0WDQ6 (revision 1)
    Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
    MAC: cc:50:e3:ab:5e:30
    Uploading stub...
    Running stub...
    Stub running...
    Configuring flash size...
    Auto-detected Flash size: 16MB
    Flash params set to 0x024f
    Compressed 2943432 bytes to 1861533...
    Wrote 2943432 bytes (1861533 compressed) at 0x00001000 in 165.4 seconds (effective 142.3 kbit/s)...
    Hash of data verified.
    Hard resetting via RTS pin...
    *** Done, low.js flashed. Please give your device a few seconds to reset to factory state
    To communicate with your microcontroller, connect to the Wifi:
    SSID:       low.js@ESP32 CC50E3AB5E30
    Password:   ez9gQ8zVGFBG
    In this Wifi, the microcontroller has the IP
    Note: Your device has enough flash space to support low.js Professional with on-board web-based IDE + debugger, over-the-air updating and native modules. Please check https://www.neonious.com/Store for more information!
    Thomass-MBP:testtest t.rogg$ lowsync
    Fetching file system listings...
    Reminder: No password set! Please set one via the lowsync settings set web.password="..." command. Continuing...
    ? The filesystem of the microcontroller has not been synced before, however the 
    repository on your PC has been synced with another device. How would you like to
     continue? Discard sync history and do an initial sync. This will ask you how to
     proceed where files exist both locally and remotely and differ. NO existing fil
    es or folders will be automatically overridden.
    ? The microcontroller has files in his file system (probably preinstalled exampl
    e application), the repository on your PC also. How would you like to continue? 
    Delete files on microcontroller and copy local files to microcontroller.
    Synchronization complete |██████████████████████████████| 100%
    PC => MC: +File index.js
    PC => MC: -File/Folder README.txt
    PC => MC: -File/Folder package.json
    PC => MC: -File/Folder www
    ? Would you like to show the output of the microcontroller? (Use the --monitor command line option to remove 
    this prompt and enable/disable showing of the output after sync.) Yes
    Restarting program...
    Starting monitor...
    --- User program's output: ---
    Addr: 99 -- Error: Timeout during I2C transfer
    Reinitializing i2c...
    --- Program exited. ---

  • Tested and is working as expected now.

Log in to reply