Wemos D1 Mini / ESP8266, MySensors and Analog A0



  • Hello,
    What's going on with MySensors and Wemos D1 Mini's A0 port? I have an ACS712 hall sensor connected to A0 and it works fine together with other sensors in this sketch:

    #include <Filters.h>
    
    float testFrequency = 50;                     // test signal frequency (Hz)
    float windowLength = 20.0/testFrequency;     // how long to average the signal, for statistist
    int sensorValue = 0;
    float intercept = -0.045; // to be adjusted based on calibration testing
    float slope = 0.0350; // to be adjusted based on calibration testing
    //float intercept = -0.045; // to be adjusted based on calibration testing
    //float slope = 0.0495; // to be adjusted based on calibration testing
    RunningStatistics inputStats;                 // create statistics to look at the raw test signal
    
    float current_amps; // estimated actual current in amps
    
    unsigned long printPeriod = 5000; // in milliseconds
    // Track time in milliseconds since last reading 
    unsigned long previousMillis = 0;
    
    void setup() {
      Serial.begin( 9600 );    // start the serial port
      inputStats.setWindowSecs( windowLength );
    }
    
    void loop() {
       
        sensorValue = analogRead(A0);  // read the analog in value:
        inputStats.input(sensorValue);  // log to Stats function
            
        if((unsigned long)(millis() - previousMillis) >= printPeriod) {
          previousMillis = millis();   // update time
          
          // display current values to the screen
          Serial.print( "\n" );
          // output sigma or variation values associated with the inputValue itself
          Serial.print( "\tsigma: " ); Serial.print( inputStats.sigma() );
          // convert signal sigma value to current in amps
          current_amps = intercept + slope * inputStats.sigma();
          //if (current_amps < 0.15) { current_amps = 0.00; }
          Serial.print( "\tamps: " ); Serial.print( current_amps );
          Serial.print( "\tWatts: " ); Serial.print( current_amps*230 );
        delay(1);
      }
    }
    

    ACS712 raw input floats around 720 when no load. I have calibrated it to appr. 10w tolerance. When put all this together with MySensors code, I don't get anymore any reliable numbers from A0. After stripping not related code from MySensors sketch what was left is here:

     /**
     */
    // Enable debug prints to serial monitor
    #define MY_DEBUG 1
    
    // Define this nodeID manually
    #define MY_NODE_ID 13
    
    // Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
    #define MY_BAUD_RATE 9600
    
    #define MY_GATEWAY_ESP8266
    #define MY_ESP8266_SSID "xxxxxx"
    #define MY_ESP8266_PASSWORD "xxxxx"
    
    // Set the hostname for the WiFi Client. This is the hostname
    // it will pass to the DHCP server if not static.
    #define MY_ESP8266_HOSTNAME "ESP8266-PowerSocket2"
    
    // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
    #define MY_IP_ADDRESS 192,168,0,71
    
    // If using static ip you need to define Gateway and Subnet address as well
    #define MY_IP_GATEWAY_ADDRESS 192,168,0,1
    #define MY_IP_SUBNET_ADDRESS 255,255,255,0
    
    // The port to keep open on node server mode 
    #define MY_PORT 5003      
    
    // How many clients should be able to connect to this gateway (default 1)
    #define MY_GATEWAY_MAX_CLIENTS 2
    
    #include <EEPROM.h>
    #include <SPI.h>
    #include <ESP8266WiFi.h>
    #include <MySensors.h>  
    #include <Filters.h>
    
    //------------- ACS712 related definitions -------------
    #define ACS712_ID 2
    #define ACS712_PIN A0
    int ACS712sensorValue = 0;
    //------------------------------------------------------
    
    void setup() { 
      Serial.begin(9600);
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("ESP8266 PowerSocket2", "1.0");
    }
    
    void loop() { 
    
      //-- Send ACS712 update if interval reached
      ACS712sensorValue = analogRead(A0);  // read the analog in value:
      Serial.println(ACS712sensorValue);
      wait(200);
    }
    

    It connects nicely to my home wlan, but somehow A0 is now used, changed or reserved to something else. AnalogRead(A0) just prints 65536 all the time. It seems that specifically MySensors library is somehow messing this up because when commenting it out I get correct readings from A0. I'm wondering if it has something to do with ESP8266/Arduino pinmapping? Currently I have used this table (https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h#L37-L59) to map the correct pins on the board and Arduino IDE:

    static const uint8_t LED_BUILTIN = 2;
    static const uint8_t BUILTIN_LED = 2;
    
    static const uint8_t D0   = 16;
    static const uint8_t D1   = 5;
    static const uint8_t D2   = 4;
    static const uint8_t D3   = 0;
    static const uint8_t D4   = 2;
    static const uint8_t D5   = 14;
    static const uint8_t D6   = 12;
    static const uint8_t D7   = 13;
    static const uint8_t D8   = 15;
    static const uint8_t RX   = 3;
    static const uint8_t TX   = 1;
    

    Nothing related to A0 though... Quite irritating as this is the only analog input available on Wemos... Moreover pretty much the same sketch has been working on Arduino Nano+NFR24L01. Problem with that combination was that when using statistics functions to get reliable enough data from ACS712 on top of all the other sensor functionality on the same node, I faced memory problems which are not happening with Wemos D1M. So please can someone help me with this?


  • Mod

    @Sushukka the analog pin on ESP8266 (which Wemos D1 Mini is based on) accept only 0.0-1.0 V. A voltage at or above 1.0V will be reported as 65535.

    Could that be the problem?

    If that is the case, you can probably solve it by adding a voltage divider to scale the voltage from ACS712 down to 1/5 of original (or less), seems like it is a 5V device?



  • @mfalkvidd I changed the input voltage from 5V to 3.3V to ACS712 and now it shows again some numbers. Need to do the calibration from the scratch again as the scale has now changed. So thank you for guiding the dummy further on the road. 🙂 Getting little bit tired of ESP8266's 3.3V specs. Majority of the sensors tend to be 5V and too often need to implement all kind of voltage drops, step-ups etc, to get things working. One major reason for ESP8266 usage is it's lower footprint comparing to Arduino + NFR24 and it's pretty much lost with this extra voltage crap needed.

    Also, the big question is that how in the earth this worked with the same hardware setup (only ACS712 connected to ESP8266) with another sketch where MySensors library was not included? 😮 I have a hairdryer connected to it and got reliable measurements up to 1400W. Probably would have some problems over 2000W orso when the scale would have been ended, but anyway I shouldn't get different numbers with MySensors library included?

    EDIT: Didn't work. Late night coding --> forgot to uncomment the MySensors library. Still works only without MySensors library which is strange af.


  • Mod

    @Sushukka I use almost only 3.3V devices, including Arduino Pro Mini, so for me anything using 5V is a hassle 🙂

    I don't think MySensors should affect the measurements. But there is a lot of other stuff that differs between the sketches so it could be something else.



  • @mfalkvidd Darnit, my bad. Forgot to uncomment the include MySensors.h after changing from 5V to 3.3V. Now when using 3.3V input the idle value floats around 510. I can include all the other libraries like EEPROM.h, SPI.h, ESP8266Wifi.h, Filters.h, DHT.h...MySensors library does something.
    Here is the simplest sketch for analog reading:

    const int currentPin = A0;
    void setup()
    {
     Serial.begin(9600);
    }
    
    void loop()
    {
    Serial.println(analogRead(currentPin));
    delay(200);
    }
    

    Works fine. Raw output values floats around 500 --> 660 when testing from 0-1400W so I can measure wattages reliably and high enough. However this skecth don't work until I comment MySensors.h library.

     /**
     * DESCRIPTION
     */
    // Enable debug prints to serial monitor
    #define MY_DEBUG 1
    
    // Define this nodeID manually
    #define MY_NODE_ID 13
    
    // Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
    #define MY_BAUD_RATE 9600
    
    #define MY_GATEWAY_ESP8266
    #define MY_ESP8266_SSID "xxxxxxx"
    #define MY_ESP8266_PASSWORD "xxxxxxx"
    
    // Set the hostname for the WiFi Client. This is the hostname
    // it will pass to the DHCP server if not static.
    #define MY_ESP8266_HOSTNAME "ESP8266-PowerSocket2"
    
    // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
    #define MY_IP_ADDRESS 192,168,0,71
    
    // If using static ip you need to define Gateway and Subnet address as well
    #define MY_IP_GATEWAY_ADDRESS 192,168,0,1
    #define MY_IP_SUBNET_ADDRESS 255,255,255,0
    
    // The port to keep open on node server mode 
    #define MY_PORT 5003      
    
    // How many clients should be able to connect to this gateway (default 1)
    #define MY_GATEWAY_MAX_CLIENTS 2
    
    #include <EEPROM.h>
    #include <SPI.h>
    #include <DHT.h>
    #include <ESP8266WiFi.h>
    #include <MySensors.h>  
    #include <Filters.h>
    
    //------------- ACS712 related definitions -------------
    #define ACS712_ID 2
    #define ACS712_PIN A0
    float ACS712sensorValue = 0;
    //------------------------------------------------------
    
    void setup() { 
      Serial.begin(9600);
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
     // sendSketchInfo("ESP8266 PowerSocket2", "1.0");
    }
    
    void loop() { 
    
      //-- Send ACS712 update if interval reached
      ACS712sensorValue = analogRead(A0);  // read the analog in value:
      Serial.println(ACS712sensorValue);
      delay(200);
    }
    
    

    Pretty much the simpliest MySensors sketch you can make and doing just analogRead(A0). Somehow MySensors library is screwing things up. Also I haven't found any 3.3V hall sensors out there for measuring bigger loads like 20A so the problem for this should be pinpointed somehow.


  • Mod

    @Sushukka On the second sketch you cast the result of analogRead to a float, while the first just prints the integer value. I think the cast is ok, but it would be better if you kept the difference between the sketches as small as possible.

    If I understand correctly, you get 500->660 when using the first sketch. What result do you get when using the second sketch, with the MySensors include removed? What result do you get from the second sketch when the MySensors include is present?

    According to https://github.com/esp8266/Arduino/blob/4897e0006b5b0123a2fa31f67b14a3fff65ce561/doc/reference.md#analog-input

    ADC_MODE(ADC_VCC);
    

    must be called before using analogRead. But you don't use that in any of your sketches. Maybe that is the problem? What happens if you add that?



  • @mfalkvidd said: Not sure if reading VCC has any benefits. I tried Serial.println(ESP.getVcc()); and got values around 3000 (prolly volts in four digits). It didn't change when putting load on ACS712 so it's most probably what it looks like: board's internal VCC value. Also ADC_MODE(ADC_VCC); seems to guide to the same VCC measurement. Howerver, as it was written in the link you send, I tried this too. The ADC_MODE definition line should be put outside any functions eg. after include statements. I assumed that it was define so I wrote #define ADC_MODE(ADC_VCC) and #define ADC_MODE ADC_VCC just to be sure. Still the results are the same: I get 65536 output when activating MySensors library. I have omitted the int/long type casts writing Serial.println(analogRead(A0)); in both sketch. Also if I remove MySensors library from the second sketch, I get the same ~506-510 values I get from the first sketch.


  • Mod

    @Sushukka ADC_MODE shouldn't be in a define I think. But I don't think it matters anyway, as you say it seems only to apply when reading the cpu voltage.

    I am out of ideas unfortunately.


  • Mod

    I found this https://github.com/mysensors/MySensors/blob/8e1ef13804f2737079298c63bd0d8aa7b82e7f73/core/MyHwESP8266.cpp#L94

    If I understand the code correctly, MySensors configures analogRead to always read the cpu voltage. Could that be the case? What happens if you remove this line from the MySensors library and re-upload the sketch?



  • @mfalkvidd Hehheh, now it works. I commented out the ADC_MODE line from MyHwESP8266.cpp. It seems that in my version (newest MySensors core available in Arduino IDE) the ADC_MODE line is out of the #ifdef MYDEBUG-clause. It's just a free floating line in the root of the application logic.

    int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms) {
    	// TODO: Not supported!
    	(void)interrupt1;
    	(void)mode1;
    	(void)interrupt2;
    	(void)mode2;
    	(void)ms;
    	return -2;
    }
    
    // ADC_MODE(ADC_VCC);
    
    uint16_t hwCPUVoltage() {
    	// in mV
    	return ESP.getVcc();
    }
    
    uint16_t hwCPUFrequency() {
    	// in 1/10Mhz
    	return ESP.getCpuFreqMHz()*10;
    }
    
    uint16_t hwFreeMem() {
    	return ESP.getFreeHeap();
    }
    

    Now it works perfectly. Thank you a lot for your patience mfalkvidd! There are some calibration issues when having Wifi and all other stuff up and running. Basically this is related to the statistics functions but that's no problem, I just switched back to the old algorithm and now measurement works within 10W tolerance using 5V input to sensor. Still even with MYDEBUG variable on, I very much wonder why MySensors change the only ESP8266 analog pin for internal voltage measurement.


  • Mod

    @Sushukka I agree that it is strange. I was just about to ask you to create an issue on github, but then I found this:
    https://github.com/mysensors/MySensors/issues/575



  • @mfalkvidd Thanks again. 🙂 Commented the issue too. Hopefully they get that fixed someday soon as it is quite a nasty issue for ESP8266 users.


Log in to reply
 

Suggested Topics

15
Online

11.4k
Users

11.1k
Topics

112.7k
Posts