Serial Communication

Hi Every one,
I am new with programing, but after learning few steps we have done weighing scale for crane which is at height. along with Bluetooth communication on Android mobile and local stationed second Arduino Uno.

now help needed in getting data at station Arduino with LCD as we are using serial communication with baud rate of 9600bps. Data is continually running like stock market display.

please help me in getting stable display as we are getting at Arduino which is at crane.

we have used serial communication program, which is available in library.

Can you post the code that you are having trouble with?

Did you read the how to use this forum sticky.

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {

lcd.begin(16, 2);

Serial.begin(9600);
}

void loop() {

if (Serial.available()) {

delay(100);

lcd.clear();

while (Serial.available() > 0) {

lcd.write(Serial.read());
}
}
}


referred library

Can you post a sample of the data that is coming from the crane? I think that you need to read a line at time instead of a character at a time. Then you can format the line of data to fit the LCD and display the line. The serial input basics thread will show how to read the data intro a null terminated character array (string)

Without more information on the data and a description of how you want the data displayed, that is the best that I can do to help.

@OP

This is my understanding about your project:

1. You have an UNO placed in the Crane. This is the 'Local Station'.

2. A Load Cell + HX711 Module (it measures weight that the Crane carries) is connected with the UNO.

3. The UNO is equipped with HC-05 Bluetooth Module.

4. You are located on the ground with Android Smart Phone which is paired with the Bluetooth Module of the UNO.

5. You wish to Monitor weight information on the screen of your Phone.

If your setup is similar to above, then it is fine; otherwise, please describe/explain your project so that we understand clearly what you want, and we can help you accordingly.

Thanks.
That’s Totally correct and also i am getting data at android phone.

now thing is that we want to display on LCD instead of phone. and we are getting running data

the project is like...

1.Crane+Load Cell+Hx711+Arduino uno +HC05(master)+LCD

2.Arduino Uno+HC05(Slave)+LCD (Stationed)

Or

2.Andriod Phone.

now I am ok with android phone display. but getting running data on LCD (stationed)

Without more information on the data, the structure of the data and a description of how you want the data displayed we can't help much.

Is the HC05 connected to the hardware serial port? If so, I would recommend that you switch it to a software serial port to free the hardware serial (USB) for debugging.

Repeating the question over and over does not provide the information that we need. What you want to do is really pretty easy if we have the information that we need.

Rahulrathod007:
the project is like...
1.Crane+Load Cell+Hx711+Arduino uno +HC05(master)+LCD

2.Arduino Uno+HC05(Slave)+LCD (Stationed)

Or

2.Andriod Phone.

now I am ok with android phone display. but getting running data on LCD (stationed)

Please, be specific as to saying like --

We have the following hardware setup:

1.Crane+Load Cell+Hx711+Arduino uno-1 +HC05-1(master)+I2C/P LCD-1 (16x2)

2.Arduino Uno-2+HC05-2(Slave)+I2C/P LCD-2 (16x2) (Stationed/on the ground)

Assume that the Load Cell has measured a weight of 123.756 kg; we want to see this weight information to have displayed on LCD-1 and LCD-2. (Let us Forget the Android)

A: Based on the above propositions, we would like to have your hardware set up as follow:

B: Please, try to write some codes for the setup of step-A and post here with code tags (</>).

void loop() {
 
  if (Serial.available()) {

    delay(100);

On EVERY pass through loop(), when there is Serial data to read, stuff your head in the sand for 1/10th of a second. Why? Whichever person on your team thought this was a good idea should be required to by pizza for the rest of the team for a month.

Thanks everyone for reply,

@PaulS

we are from mechanical background, so please help us.

can you share full code for receiving end which has LCD stationed.

@GolamMustafa & groundFungus

i will be back with actual pics.

People who wish to go into the future should have two skills to succeed - the ability to deal with people and the ability to sell.

can you share full code for receiving end which has LCD stationed.

Without seeing the code at the sending end? No.

If the code you posted above is the code on the receiving end, the biggest problem is the use of delay(). Stop doing that, and all of your problems just might go away.

we are from mechanical background

So, why would you think it appropriate to use the stupidest tool in the toolbox? Forget, forever, that the Arduino can delay(). You should NEVER need to do that in a real program.

The most important reference to the tutorial covering Serial Input Basics and methods on how to send and receive data went flying by in post #3. Did you read it?

Here is code at Crane Arduino.

#include "HX711.h"  
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
#define DOUT  3
#define CLK  2
float weight=0;
const int cal=6;
const int up=5;
const int down=4;
const int x100=1;
int readingup,readingdown,readingcal,readingx100,cf=0,a[2]={100,1000},i=0;
float calibration_factor =-50400; //this value is calculated according to instructions in report 
HX711 scale(DOUT, CLK); //using the Hx711 in 128 gain mode by default
void setup() 
{
  Serial.begin(9600);
  lcd.begin(16,2);
  pinMode(cal,INPUT);
  pinMode(up,INPUT);
  pinMode(down,INPUT);
  pinMode(x100,INPUT);
  scale.set_scale(); // initially calibrating the scale with zero value
  scale.tare(); //resets the scale to 0
  long zero_factor = scale.read_average(10); //stores the average of 10 readings from the ADC when there is no weight on pan
}
void loop() 
{
  readingcal=digitalRead(cal);
  if(readingcal==HIGH) //this section gets activated when CAL button is ON for calibration
  {
    if(cf==0)//in this section we will give some instructions for calibration once
    {
      lcd.clear();
      lcd.setCursor(2,0);
      lcd.print("Calibration   ");
      lcd.setCursor(4,1);
      lcd.print("Starts!        ");
      delay(3000);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Place 1T weight");
      lcd.setCursor(0,1);
      lcd.print("or known weight.");
      delay(4000);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Press '+' when  ");
      lcd.setCursor(0,1);
      lcd.print("weight is small.");
      delay(2500);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Press '-' when  ");
      lcd.setCursor(0,1);
      lcd.print("weight is big.  ");
      delay(2500);
      cf=1; // this variable helps us to read the instructions once and for the rest of time calibration() function is called 
    }
    calibration();
  }
  else //otherwise to measure the weights
  {
    display2();
    cf=0; //this variable helps us to read the instructions ONCE when the CAL button is switched ON
  }
}
void calibration()  //this is the general function of Calibration
{
  readingup=digitalRead(up); //reads the logic at pin 5 to increase the calibration factor
  readingdown=digitalRead(down); //reads the logic at pin 4 to decrease the calibration factor
  readingx100=digitalRead(x100); //reads the logic at pin 1 to inc/dec the calibration factor by 100 times
  if(readingx100==HIGH)
  {
    i=1; //i is the index of array used at top that contains only two values 10 and 100,
    //it provides the factor by which we are inc/dec the calibration factor
  }
  else {i=0;} //if x100 is off then by default we increase or decrease the calibration factor by 10 times
     if(readingup==HIGH)
  {
    calibration_factor+=a[i];//increasing the calibration factor by 10/100 times
    delay(80);
  }
  if(readingdown==HIGH)
  {
    calibration_factor-=a[i];//decreasing the calibration factor by 10/100 times
    delay(80);
  }
  display1();//as we used two different displays for two modes. NOrmal mode and Calibration mode.. 
  //this is for calibration mode
}
void display1()//calibration mode display
{
  scale.set_scale(calibration_factor); //the value in calibration factor is obtained by calibration it with known weights
  weight=scale.get_units(); //stores the average of weight readings from the ADC according to the calibration factor
  if(weight<0)
  {weight=0;}
  lcd.setCursor(0,0);
  lcd.print("Weight: ");
  lcd.setCursor(8,0);
  lcd.print(weight,4); //displays the weight in 4 decimal places only for calibration
  lcd.setCursor(14,0);
  lcd.print("T");
  lcd.setCursor(0,1);
  lcd.print("Value: "); //display the calibration factor so that it is easy to inc/dec it and reading it at the same time
  lcd.setCursor(7,1);
  lcd.print(calibration_factor);
}
void display2()//display of normal mode
{
  scale.set_scale(calibration_factor);
  weight=scale.get_units(); 
  if(weight<0)
  {weight=0;}//if the weight is negative then show it zero
  lcd.setCursor(0,0);
  lcd.print("**Weight Scale:*");
  lcd.setCursor(0,1);
  lcd.print("Weight: ");
  lcd.setCursor(8,1);
  lcd.print(weight,2);//displaying the weight in two decimal places. As 0.01 accuracy is required
  Serial.print("weight:");
  Serial.print (weight);
  Serial.println("T");
  lcd.setCursor(12,1);
  lcd.print("T  ");
}

code at receiving Arduino i.e. stationed

#include <LiquidCrystal.h>

// Set the LCD address to 0x3F for a 16 chars and 2 line display
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

void setup()
{
  lcd.begin(16,2);  
  // Initialize the serial port at a speed of 9600 baud
  Serial.begin(9600);
}

void loop()
{
  // If characters arrived over the serial port...
  if (Serial.available()) {
    // Wait a bit for the entire message to arrive
    // Clear the screen
    lcd.clear();
    
    while (Serial.available() > 0) {  
      lcd.setCursor(0,0);
  lcd.print("**Weight Scale:*");
  lcd.setCursor(0,1);
  lcd.print("Weight: ");
  lcd.setCursor(8,1);
  lcd.write(Serial.read());

  lcd.setCursor(12,1);
  lcd.print("T  ");   
     
    
    }
  }
}

LCD at Crane.jpg

LCD at Stationed.jpg

In the code at crane Arduino code, replace this part:

lcd.print(weight,2);//displaying the weight in two decimal places. As 0.01 accuracy is required
  Serial.print("weight:");
  Serial.print (weight);
  Serial.println("T");
  lcd.setCursor(12,1);

With this:

lcd.print(weight,2);//displaying the weight in two decimal places. As 0.01 accuracy is required
  Serial.print("<");  // send start marker *******
  Serial.print (weight); // send weight ******** 
  Serial.println(">");  // send end marker ******
  lcd.setCursor(12,1);

There is no need to send “Weight” and “T”, it is useless data.

And here is the whole code for the code at receiving Arduino:

#include <LiquidCrystal.h>

// Set the LCD address to 0x3F for a 16 chars and 2 line display
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

void setup()
{
   lcd.begin(16, 2);
   // Initialize the serial port at a speed of 9600 baud
   Serial.begin(9600);
   lcd.setCursor(0, 0);
   lcd.print("**Weight Scale:*");  // don't need to write this over an over
}

void loop()
{

   recvWithStartEndMarkers();
   if(newData == true) // only print to LCD if there is new data
   {   
   lcd.setCursor(0, 1);
   lcd.print("Weight: ");
   lcd.print(receivedChars);
   lcd.print("    "); // make sure that old data is over written
   lcd.setCursor(14, 1);
   lcd.print("T");
   newData = false;
   }


}

void recvWithStartEndMarkers()
{
   static boolean recvInProgress = false;
   static byte ndx = 0;
   char startMarker = '<';
   char endMarker = '>';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();

      if (recvInProgress == true)
      {
         if (rc != endMarker)
         {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars)
            {
               ndx = numChars - 1;
            }
         }
         else
         {
            receivedChars[ndx] = '\0'; // terminate the string
            recvInProgress = false;
            ndx = 0;
            newData = true;
         }
      }
      else if (rc == startMarker)
      {
         recvInProgress = true;
      }
   }
}

void showNewData()
{
   if (newData == true)
   {
      Serial.print("This just in ... ");
      Serial.println(receivedChars);
      newData = false;
   }
}

This uses code from the serial input basics tutorial, example #3. I know that it seems complex, but the start and end markers insure that the data will be read without errors and the program does not block.

@OP

1. Add the following codes (at the appropriate place) in the sketch of Crane Arduino; these codes will transmit the weight information (float content of weight variable) from Crane Arduino to Station Arduino using of Software UART Port. I have tested these codes using Direct Connection, Serial Monitor and Test Data. The codes should work for HC05 (Bluetooth) and HC12 (Radio).

2. Add the following codes (at the appropriate place) in the sketch of Station Arduino; these codes will receive the weight information (float content of weight variable) from Crane Arduino using Software UART Port and then will show on the Serial Monitor. Add codes to show the value on LCD.

3. Crane Arduino Code:

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3); //SRX/STX pin of UNO
float weight = 13.75;   //test data
void setup() 
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop() 
{
  Serial.println(weight, 2);
  SUART.print(':');  //Beginning Mark of transmit
  SUART.print(weight, 2);
  SUART.print('#'); //Ending Mark of transmit
  delay(1000);

}

4. Station Codes

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3); //SRX/STX pin of UNO
char dataArray[10] = "";
bool flag1 = false;
byte x;
int i = 0;
float weight = 00.0;

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  if (SUART.available() > 0)
  {
    if (flag1 == false)
    {
      x = SUART.read();
      if (x == ':')
      {
        flag1 = true;
      }
    }
    else
    {
      x = SUART.read();
      if (x != '#')
      {
        dataArray[i] = x;
        i++;
      }
      else
      {
        weight = atof(dataArray);  //converted back to float format if the ASCII formatted weight
        Serial.println(weight, 2);    //lcd.print(weight, 2); will show on LCD
        i = 0;
        flag1 = false;
      }
    }
  }
}

@groundFungus

Thanks a lot. Its working fabulously and as expected.

now one more help needed, we want add alarm/hotter/red light signal, if crane lifts more weight than capacity.

I made additions to the station code to illustrate how to trigger an action at a threshold with hysteresis and flashing a light using the blink without delay method. There is an output (steady on or off) for a siren, bell or whatnot and an output for flashing a light with adjustable frequency.

To illustrate coding, provided with no warranty.

// program for crane station LCD with alarms

#include <LiquidCrystal.h>

const float CAPACITY = 10.00; // 10 Ton alarm on threshold
const float OFFSET = 9.50;  // alarm off offset.  Adds hysteresis.

const unsigned long FLASHTIME = 500;

// Set the LCD address to 0x3F for a 16 chars and 2 line display
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

const byte sirenPin = 7;
const byte lightPin = 6;

boolean alarmState = false;

void setup()
{
   lcd.begin(16, 2);
   // Initialize the serial port at a speed of 9600 baud
   Serial.begin(9600);
   pinMode(sirenPin, OUTPUT);
   pinMode(lightPin, OUTPUT);
   lcd.setCursor(0, 0);
   lcd.print("**Weight Scale:*");
}

void loop()
{

   recvWithStartEndMarkers();
   if (newData == true) // only print to LCD if there is new data
   {
      lcd.setCursor(0, 1);
      lcd.print("Weight: ");
      lcd.print(receivedChars);
      lcd.print("    "); // make sure that old data is over written
      lcd.setCursor(14, 1);
      lcd.print("T  ");
      float weightF = atof(receivedChars);
      if (weightF >= CAPACITY)
      {
         alarmState = true;
      }
      else if (weightF < OFFSET)
      {
         alarmState = false;
      }
      newData = false;
   }
   if (alarmState == true)
   {
      alarmOn();
   }
   else
   {
      alarmOff();
   }
}

void alarmOn()
{
   digitalWrite(sirenPin, HIGH);
   static unsigned long flashTimer = 0;
   if (millis() - flashTimer >= FLASHTIME)
   {
      flashTimer = millis();
      digitalWrite(lightPin, !digitalRead(lightPin));      
   }
}

void alarmOff()
{
   digitalWrite(sirenPin, LOW);
   digitalWrite(lightPin, LOW);
}

void recvWithStartEndMarkers()
{
   static boolean recvInProgress = false;
   static byte ndx = 0;
   char startMarker = '<';
   char endMarker = '>';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();

      if (recvInProgress == true)
      {
         if (rc != endMarker)
         {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars)
            {
               ndx = numChars - 1;
            }
         }
         else
         {
            receivedChars[ndx] = '\0'; // terminate the string
            recvInProgress = false;
            ndx = 0;
            newData = true;
         }
      }
      else if (rc == startMarker)
      {
         recvInProgress = true;
      }
   }
}

void showNewData()
{
   if (newData == true)
   {
      Serial.print("This just in ... ");
      Serial.println(receivedChars);
      newData = false;
   }
}

Hi groundFungus
need further help, want to display battery voltage and Battery low signal of crane arduino on station arduino.

Right now, crane load more than capacity has been postponed.

Thanks

Will the battery voltage come to the station Arduino along with the weight reading? Then the station program will use the received battery voltage and a threshold, set in the station code, to trigger the low battery alarm?

Refer to example #5 of the serial input basics tutorial to see how to receive and parse multiple data items. The code for sensing the threshold and setting an alarm are in the previous code.