Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Atmega32 Serial read idea please

Status
Not open for further replies.

johnny78

Full Member level 5
Full Member level 5
Joined
Jun 28, 2017
Messages
269
Helped
1
Reputation
2
Reaction score
5
Trophy points
1,298
Activity points
3,453
hi guys
im working on a project to read from electronic scale & display it on 5 7segment digits
now its all work great but there is something im looking for a solution to fix it
when i set the scale to send continous data the display works but sometimes when the scale is unstable
it sends 0 to the serial port then work again after it get stable
here is the code coded in arduino Ide
im looking for an idea to delay the display when the weight is 0

thanks
Johnny

Code:
void loop() {

  if ((startup) == 0) {
    sevseg.setChars("-----");
  }

  if (stringComplete) {
    digitalWrite(Led , LOW);
    String lcdData;
    lcdData.reserve(30);
    lcdData = inputString;
    lcdData.replace("N", "");
    lcdData.replace("S", "");
    lcdData.replace(" ", "");

    weight = lcdData.toFloat();

    if (digitalRead(modeSelect) == HIGH) {
      sevseg.setNumberF(weight, 3);
    }
    else if (digitalRead(modeSelect) == LOW) {
      sevseg.setNumberF(weight, 2);
    }
    startup = 1;
    // // clear the string:
    inputString = ("");
    stringComplete = false;

  }


  sevseg.refreshDisplay(); // Must run repeatedly
}

void serialEvent() {
  if (stringComplete == false) {
    while (Serial.available()) {
      // get the new byte:
      char inChar = (char)Serial.read();
      // add it to the inputString:

      if (stringComplete == false) {
        if ((inChar == 'N') || (inChar == 'S')) {
          serialDataState = 1;
        }

        if ((serialDataState == 1) && (inChar != '\r')) {
          inputString += inChar;
        }
        else
          stringComplete = true;
        }
      }
    }
  }
 
Last edited:

h
Hi,

What about using interrupts?

Klaus
how & where ?
i didnt think about it
i just tried to add this line but now i cant see 0 result at all
Code:
 if ((weight) != 0) {
      if (digitalRead(modeSelect) == HIGH) {
        sevseg.setNumberF(weight, 3);
      }
      else if (digitalRead(modeSelect) == LOW) {
        sevseg.setNumberF(weight, 2);
      }
    }
 

Hi,

Interrupt is good for regular jobs, like the display update.
But it´s also good for timing control, to avoid busy waits.
And it´s good to react on UART input.

I recommend at least to do the timing and display in an ISR.
So then you just write the "values to display" in a variable.... and you don´t have to care about it.

Maybe useful:
If you have 5 x 7segment and you need to multiplex them:
So use an update rate of 50Hz and for 5 digits you need to run the ISR 250 times/s.
Increment a counter that is accessable in main loop, so you know every count equals exactly 4ms.

Klaus
 
Simply test for 0 and if 0 display the last reading, eg. leave it unchanged,
or simply do not write to display. If you want to display a 0 when weight is
truly 0 then use a delay such that if scale stays at 0 for some minimum time
that becomes a legit reading and then display. If < min time it gets ignored.

Simply flags can handle all this if time is real short that delineates a legit versus
false reading. If long then use a timer interrupt or just poll it. Or if you know loop
time to perform measurement just count a number of samples to get the necessary
requisite delay as a test.


Regards, Dana.
 
Last edited:

    johnny78

    Points: 2
    Helpful Answer Positive Rating
Simply test for 0 and if 0 display the last reading, eg. leave it unchanged,
or simply do not write to display. If you want to display a 0 when weight is
truly 0 then use a delay such that if scale stays at 0 for some minimum time
that becomes a legit reading and then display. If < min time it gets ignored.

Simply flags can handle all this if time is real short that delineates a legit versus
false reading. If long then use a timer interrupt or just poll it. Or if you know loop
time to perform measurement just count a number of samples to get the necessary
requisite delay as a test.


Regards, Dana.
this is what i was thinking of
Code:
 if ((weight) != 0) {
      if (digitalRead(modeSelect) == HIGH) {
        sevseg.setNumberF(weight, 3);
      }
      else if (digitalRead(modeSelect) == LOW) {
        sevseg.setNumberF(weight, 2);
      }
    }
im ignoring to display the value if the read is 0
but i cant display 0 now
advice me where to use a delay loop to check its real 0

thanks
--- Updated ---

it works

Code:
 if ((weight) != 0) {
      if (digitalRead(modeSelect) == HIGH) {
        sevseg.setNumberF(weight, 3);
      }
      else if (digitalRead(modeSelect) == LOW) {
        sevseg.setNumberF(weight, 2);
      }
    }

    if ((weight) == 0) {
      readDelay ++;
      if ((readDelay) == 100) {
        readDelay = 0 ;
        if (digitalRead(modeSelect) == HIGH) {
          sevseg.setNumberF(weight, 3);
        }
        else if (digitalRead(modeSelect) == LOW) {
          sevseg.setNumberF(weight, 2);
        }
      }
any other better way to do this ?
thanks

Johnny
 
Last edited:

Something like this -

Code:
Main( ) {
    while( 1 ) {
        weight = readAtoD();
        readelay = ( weight == 0 ) ? readelay++ : 0;
        if ( ( weight > 0 ) || ( readelay == 100 ) ) {
            displayweight( );
            readelay = 0;
        }
    }

}
 

    johnny78

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top