SpenceKonde / megaTinyCore

Arduino core for the tinyAVR 0/1/2-series - Ones's digit 2,4,5,7 (pincount, 8,14,20,24), tens digit 0, 1, or 2 (featureset), preceded by flash in kb. Library maintainers: porting help available!
Other
545 stars 141 forks source link

Strange behaviour - after powercycle MH-Z19 stops working #662

Closed Knochi closed 2 years ago

Knochi commented 2 years ago

Hi,

i wrote this to the MH-Z19 library (by WifWaf) my issue first, but without any reasonable result (signals look good, checked with oscilloscope).

so i have an ATTiny1614 (16kB Flash, 2kB RAM) with megaTinyCore, a 4-digit serial display and the MHZ-19C. I'm using hardware serial to save memory. When i flash the code everything works as expected but when i power cycle the board i get error 3 "Received data does not match the usual syntax expected". Flash memory is at 31% and global variables consume 10%. I tried additionally without the LED Display and just LED to signal function (26% / 10% memory usage), with the same result.

If it is a memory problem, why does it work right after flashing?

#include <Arduino.h>
#include "MHZ19.h"
#include <TM1637Display.h>

//Pins for 7-Segment
#define CLK 7
#define DIO 6

MHZ19 myMHZ19;                    // Constructor for CO2 Sensor
TM1637Display display(CLK, DIO);  // Constructor for 7-Segment

unsigned long getDataTimer = 0;
uint16_t errorCode=0;

void setup()
{
    display.setBrightness(0x05);
    Serial.begin(9600);                                     // Device to MH-Z19 should not be changed

    //mySerial.begin(BAUDRATE);                               // (Uno example) device to MH-Z19 serial start   
    myMHZ19.begin(Serial);                                // *Serial(Stream) refence must be passed to library begin(). 
    myMHZ19.printCommunication();    

    myMHZ19.autoCalibration(true);                              // Turn auto calibration ON (OFF autoCalibration(false))
    display.showNumberDec(millis(),false);
    delay(2000);
    display.showNumberDec(0,true);
}

void loop()
{   
    if (millis() - getDataTimer >= 2000)
    {
        int CO2; 

        /* note: getCO2() default is command "CO2 Unlimited". This returns the correct CO2 reading even 
        if below background CO2 levels or above range (useful to validate sensor). You can use the 
        usual documented command with getCO2(false) */

        CO2 = myMHZ19.getCO2();                             // Request CO2 (as ppm)
        if(myMHZ19.errorCode ==  RESULT_OK)
          display.showNumberDec(CO2,false);
        else{
          display.showNumberDec(myMHZ19.errorCode,true);
        }
        getDataTimer = millis();
    }
}
SpenceKonde commented 2 years ago

Certainly doesn't look like it would be a memory problem. What's actually coming in the through serial?

Somehow it's ending up with bad data coming in. Maybe it's picking up the middle of the message, and doesn't sort itself out?

More information is needed to conclude that this is a defect in the core. I think knowing what characters it's actually seeing come into the serial port will make the nature of the problem clear.....

SpenceKonde commented 2 years ago

This issue will be closed if I don't hear more word in a few days. It is most likely that one device is powering up faster than the other and missin part of the initial communication, or that one of them has not initialized their USART at all when the other starts listening, resulting in the first character, when it finally turns on the port being misinterpreted, because the pin is going from an undefined/floating state to a defined one, since USART has no clock, that sort of thing tends to be seen as a weird nonsense character. there are both hardware and softeware approaches to dealing with it but without knowing what it;s seeing vs what it;s expecting, and ideally a scope trace of the line, i can't make much of a recommendation

Knochi commented 2 years ago

I appreciate you are still watching this. I will conduct a few test the next days. I guess it’s a library problem, because I saw some weird communication. Nevertheless it‘s still quite confusing that it works directly after flashing and stops working after a powercycle.

SpenceKonde commented 2 years ago

I think a capture of the serial communication will make everything clear. One thing I routinely do is take a couple of extra serial adapters, and tie their grounds to the common ground, and each RX of these extra serial adapters to one of the data lines, then open them in serial console programs (not the Arduino IDE's excuse for a serial console), and then reproduce the problem Then, I have a record of what is sent by both parties and can see how it differs from the case when it does work.

USART is by far the easiest of the ports to spy on, and the data revealed through this investigation will lay bare the nature of the problem.

My gut instinct tells me that the AVR is starting up faster than the target device resulting in the initial communication being gibberish

SpenceKonde commented 2 years ago

I have made several sugestions and requests for additional information that I would need to investigate. It has not been forthcoming. Closing this as OP has provided no information that would be required for an investigation.

Knochi commented 2 years ago

Sorry for not replying. I tested the Sensor now with the final hardware (no breadboard) and it seems to work pretty stable. No idea what was wrong with the other setup. Sorry for confusion.