[Solved] I need to return a single value from incoming serial data...

Post here all questions related to LibMaple core if you can't find a relevant section!
LORDHADES
Posts: 24
Joined: Thu Nov 19, 2020 4:53 am

[Solved] I need to return a single value from incoming serial data...

Post by LORDHADES »

Hey all !!! Hope you're doing well...

I am new to STM32 and Arduino, and I'm doing a project, which is so difficult for me. I'm trying to get weight data from digital weighing scale through STM32f1, and print current weight on a thermal printer. It's a prototype for my college project.

Setup : Digital weighing scale using Renesas chip connected to one channel of Max232, another channel of Max232 connected to STM32. STM32 is connected to PC via FTDI232 serial to USB converter. A push button is attached to STM32, to facilitate data printing on serial monitor when enabled.

I managed to get the weight data on serial monitor on button press. But the problem is the weight gets printed several times even if the button is pressed for 1 second. If I try some other method, it returns invalid characters infinitely.

For the prototype, I need only current weight data to return. But I have no idea on doing that.

I hope somebody has any suggestions or some help regarding this issue. Thanks in advance.

Forgive me if my English was bad. It isn't my mother tongue. :roll:

P.S. I'm attaching the code I wrote. I hope someone will be able to help me. If there is need for circuit/connection diagram, I can provide. :roll:
I tried to buffer incoming serial values to print current value. But it ended up in vain... :(

I used this tutorial for preliminary setup : "https://www.instructables.com/Getting-S ... duino-IDE/"
Arduino IDE: v1.8.13(Windows Store 1.8.42.0) from Microsoft store
Board Manager: STM32F1XX/GD32F1XX by stm32duino v2020.11.14
Additional board manager URL: "http://dan.drown.org/stm32duino/package ... index.json"

Code: Select all


int inByte;  
const int buttonPin = PB10;
int buttonState;

char recArray[30];
int debouncecnt = 0;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  Serial2.begin(9600);
  }

void loop() {
  
  buttonState = digitalRead(buttonPin);
  if(buttonState == LOW)
  {
    debouncecnt++;
  }
  
  if (debouncecnt > 100000)
  {
    Serial.println(debouncecnt);
    debouncecnt = 0;
    
    int cnt = 0;
    clearArray();
    Serial2.flush();
    while(true)
    {
      if(Serial2.available()>0)
      {
        byte tmp = Serial2.read();
        if(tmp == '\r' || tmp == '\n')
        {
          break;
        }
        else
        {
          recArray[cnt] = tmp;
          cnt++;
          
          if(cnt > 30)
          {
            break;
          }
        }
      }
      
    }
    Serial.println(recArray);
  }
}

void clearArray()
{
  for(int i = 0; i < 30; i++)
  {
    recArray[i] = '\0';
  }
}
Last edited by LORDHADES on Fri Dec 04, 2020 7:44 am, edited 5 times in total.
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: I need to return a single value from incoming serial data...

Post by stevestrong »

Edit your post and put the code part into code tags, otherwise it is unreadable.

viewtopic.php?f=2&t=301
Which core do you use?
LORDHADES
Posts: 24
Joined: Thu Nov 19, 2020 4:53 am

Re: I need to return a single value from incoming serial data...

Post by LORDHADES »

stevestrong wrote: Thu Nov 19, 2020 8:21 am Edit your post and put the code part into code tags, otherwise it is unreadable.
Sorry sir... Forgive me if I had committed any mistakes. I've done editing it. I've also added required details.
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 27
Location: Prudnik, Poland

Re: I need to return a single value from incoming serial data...

Post by GonzoG »

LORDHADES wrote: Thu Nov 19, 2020 5:27 am
I managed to get the weight data on serial monitor on button press. But the problem is the weight gets printed several times even if the button is pressed for 1 second. If I try some other method, it returns invalid characters infinitely.
....
If you want to use buttons without repeating while button is pressed you want to send data only when there is a change in button state.
For this you need a global variable to store previous button state;

Code: Select all

#define buttonPin PA1
bool prevButtonState=1;  //1 for pulled up pin, 0 for pulled down pin.

void loop
{
....
  bool buttonState = digitalRead(buttonPin);
  if(buttonState != prevButtonState) //button was just pressed or released
  {
    delay(5); //debounce delay
    prevButtonState=buttonState;
    if(!buttonState) //button was pressed
    {
  	Serial.println("pressed");
    }
    else
    {
  	Serial.println("released");
    }
  }
}
Also your debounce method isn't good. It just counts loop cycles when button is pressed.
I know that many are using software debouncing but I prefer RC filters (but I often use interrupts). I start with 10k resistor and 10nF capacitor.

I've added debounce delay as it's the simplest way to debounce buttons but it's not a good way. There are many good examples on the internet using time (millis) or reading port (e.g when program reads 8 LOW/HIGH states in a row)


As for the whole program, I would go different way.
1. don't wait for button to read data from scale. Read them continuously, but set a flag if they are complete or not so you don't send incomplete data.
2. If you get weight from scale, store it in variable.
3. if you press button, send stored data.
LORDHADES
Posts: 24
Joined: Thu Nov 19, 2020 4:53 am

Re: I need to return a single value from incoming serial data...

Post by LORDHADES »

Thanks a lot for replying, Sir. I started learning arduino last week only, that's why this much difficulty. :cry:
My previous output on serial monitor was:

0.900 Kgs
0.900 Kgs
0.900 Kgs
0.900 Kgs
0.902 Kgs
0.900 Kgs
0.900 Kgs
0.900 Kgs
0.900 Kgs

*within a second of pressing button

Loads of thanks for your suggestions... :D I'll try and post the results, Sir..
LORDHADES
Posts: 24
Joined: Thu Nov 19, 2020 4:53 am

Re: I need to return a single value from incoming serial data...

Post by LORDHADES »

Code: Select all

#define buttonPin PA1
bool prevButtonState=1;  //1 for pulled up pin, 0 for pulled down pin.

void loop
{
....
  bool buttonState = digitalRead(buttonPin);
  if(buttonState != prevButtonState) //button was just pressed or released
  {
    delay(5); //debounce delay
    prevButtonState=buttonState;
    if(!buttonState) //button was pressed
    {
  	Serial.println("pressed");
    }
    else
    {
  	Serial.println("released");
    }
  }
}
This code doesn't work... :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry:
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

Re: I need to return a single value from incoming serial data...

Post by mlundin »

Too bad but not much we can help with, your code is incomplete so we cannot test it.

How is the button connected ? What do you do in the setup function? What, if anything, happens when you run the program?
LORDHADES
Posts: 24
Joined: Thu Nov 19, 2020 4:53 am

Re: I need to return a single value from incoming serial data...

Post by LORDHADES »

mlundin wrote: Fri Nov 27, 2020 8:10 am Too bad but not much we can help with, your code is incomplete so we cannot test it.

How is the button connected ? What do you do in the setup function? What, if anything, happens when you run the program?

Code: Select all

int inByte;
const int buttonPin = PA0;     
const int ledPin =  PC13;      
int is_button_press = 0;         
int debounce_delay = 300;

void setup() 
{
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  Serial2.begin(9600);
}

void loop() 
{
  is_button_press = digitalRead(buttonPin);

  if (Serial2.available() || is_button_press == HIGH) 
  {
    delay(debounce_delay);
    if(is_button_press == HIGH)
    {
      digitalWrite(ledPin, HIGH);
    }
    inByte = Serial2.read();
    digitalWrite(ledPin, HIGH);
    Serial.write(inByte);
    delay(100);
  } 
  
  else 
  
  {
    digitalWrite(ledPin, LOW);
  }
}
The above code is the one I used. You can see, I've attached push button to pin PA0 and ground.

If I run the code, the weight gets printed even if the button is low. Plus it continuously gets printed on the serial monitor, it doesn't cares about the button being high or low. Additionally, invalid characters are printed with weight when button is on low. Those invalid characters stops appearing when button is on high state. But the problem is, the weight is needed to be print only once, when the button is pressed, so it can be printed using thermal printer.

Loads of thanks for your reply, brother... :D
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 27
Location: Prudnik, Poland

Re: I need to return a single value from incoming serial data...

Post by GonzoG »

Remove "Serial.available()" from "if".
Serial.available() checks if there are any incoming data in buffer.
If you just want to check it there is active connection on serial, use:

Code: Select all

if(Serial || button!=prev_button)
LORDHADES
Posts: 24
Joined: Thu Nov 19, 2020 4:53 am

Re: I need to return a single value from incoming serial data...

Post by LORDHADES »

GonzoG wrote: Fri Nov 27, 2020 11:45 am Remove "Serial.available()" from "if".
Serial.available() checks if there are any incoming data in buffer.
If you just want to check it there is active connection on serial, use:

Code: Select all

if(Serial || button!=prev_button)
Loads of thanks brother... :D
Post Reply

Return to “General discussion”