I am working on a project using Arduino Mega 2560. I have an oxygen monitor module. I have successfully been able to receive data from analog outputs. Now i want to get data digitally but it uses tx and rx for communication. Can someone help me with this? I've not been able to write a code for this. Which library do i use?
The code in Reply #1 will show the bytes in the data on the Serial Monitor. However it seems the data is sent in binary form so the raw byte values may not make sense.
The following code is a small adaptation of a suggestion I made in another Post a few days ago. By copying the received data to a struct it gets "parsed" automatically.
// define the stuct at the top pf the program
struct MyDataStruct {
byte ack;
byte lb;
byte cmd;
int concent;
int flow;
int temp; // I don't know the correct name
byte st1;
byte st2;
byte crc;
};
MyDataStruct myData;
byte myDataLen = sizeof(myData);
byte* mdata = reinterpret_cast<byte*>(&myData);
// this code to transfer the data to the struct goes into loop
if (Serial1.available() >= myDataLen) {
for (byte n = 0; n < myDataLen; n++) {
*(mdata + n) = Serial1.read();
}
// make sure the serial buffer is empty
while (Serial1.available() > 0) {
byte dumpByte = Serial1.read();
}
}
// example of how to view a value on the Serial Monitor
Serial.println(myData.concent);
...R
EDIT 29 Oct 2020 to insert "byte" before "myDataLen = sizeof(myData);"
Hi robin2. I was actually getting garbage values. Can you help me with this- "// define the stuct at the top pf the program"
I got one doubt. The RXD pin on the module goes to RX1 and TXD pin goes to TX1. Is that correct?
bonyl:
Can you help me with this- "// define the stuct at the top pf the program"
[/quote]
It will be much easier to help if you post the program that represents your best attempt and tell us in detail what it actually does and what you want it to do that is different. That way we can focus on the parts you need help with rather than wasting time on things that you can do.
In particular note the advice to Auto format code in the IDE and to use code tags when posting code here as it prevents some combinations of characters in code being interpreted as HTML commands such as italics, bold or a smiley character, all of which render the code useless
Hi Robin, this code is giving me random values.
Let me just explain what I'm trying to do here. I am working on building an oxygen concentrator. The compressed air is passed through a molecular sieve and the nitrogen in the air is trapped and only oxygen is allowed to pass. Now i want to check the purity of the oxygen in real time with the help of this oxygen monitor module. I have attached the datasheet in previous reply. This sensor measures both flow (Litres per minute) and oxygen (Percentage). I tested these values in analog form and they are proper. Now i want to get it digitally.
Can i get both flow and oxygen level with TX1 and RX1 pins.
If yes, how do i do it?
I am a PLC programmer and a noob in scripting and communication Please help.
struct MyDataStruct {
byte ack;
byte lb;
byte cmd;
int concent;
int flow;
int temp; // I don't know the correct name
byte st1;
byte st2;
byte crc;
};
MyDataStruct myData;
byte myDataLen = sizeof(myData);
byte* mdata = reinterpret_cast<byte*>(&myData);
void setup(){ // define the stuct at the top pf the program
Serial.begin(9600);
Serial1.begin(9600);
}
void loop(){
// this code to transfer the data to the struct goes into loop
if (Serial1.available() >= myDataLen) {
for (byte n = 0; n < myDataLen; n++) {
*(mdata + n) = Serial1.read();
}
// make sure the serial buffer is empty
while (Serial1.available() > 0) {
byte dumpByte = Serial1.read();
}
}
// example of how to view a value on the Serial Monitor
Serial.println(myData.concent);
}
bonyl:
Hi Robin, this code is giving me random values.
You are printing values to the Serial monitor without any regard for whether a new message has been received from the oxygen module. When I suggested the code in Reply #2 I had assumed you would adapt the idea into a program of your own.
Try this version.
struct MyDataStruct {
byte ack;
byte lb;
byte cmd;
int concent;
int flow;
int temp; // I don't know the correct name
byte st1;
byte st2;
byte crc;
};
MyDataStruct myData;
byte myDataLen = sizeof(myData);
byte* mdata = reinterpret_cast<byte*>(&myData);
bool newData = false;
void setup(){ // define the stuct at the top pf the program
Serial.begin(9600);
Serial1.begin(9600);
}
void loop(){
// this code to transfer the data to the struct goes into loop
if (Serial1.available() >= myDataLen) {
for (byte n = 0; n < myDataLen; n++) {
*(mdata + n) = Serial1.read();
}
// make sure the serial buffer is empty
while (Serial1.available() > 0) {
byte dumpByte = Serial1.read();
}
newData = true;
}
if (newData == true) {
// example of how to view a value on the Serial Monitor
Serial.println(myData.concent);
newData = false;
}
}
Thank you Robin. I tried the new version. But i'm getting the values as attached. What can be the problem? Will both the values (flow and O2) be shown together?
Robin2:
Then it would be better to receive the complete message as a series of bytes and subsequently reconstruct the ints the correct way round.
Or maybe receive the message into my struct and subsequently swap the bytes at the int positions.
I'd go with the former method. Given that there's a defined packet rate (once every 500ms), framing bytes, and a checksum, it's a simple matter to determine that you've captured a valid, properly-aligned packet.
Then, use bitwise operations to correctly place the high/low bytes into the variables.
Also, use a proper data type (i.e. uint16_t) instead of plane old 'int'. I always worry there will be some implementation-dependent funniness when doing bit shifts on signed data types.
The above technique ensure that the code is processor and implementation independent.