Go Down

Topic: Explanation of program needed (Read 850 times) previous topic - next topic

moomoo

#include <NewSoftSerial.h>
NewSoftSerial nss(5,8); // Put your TX and RX pins here, in the correct order

byte vals[3];
int heartRate, oxyLevel;

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

void loop()
{
  if(nss.available() >= 3)
  {
    Serial.print("Heart rate: ");
    Serial.println(heartRate);
    Serial.print("Oxygen level: ");
    Serial.println(oxyLevel);
   
    vals[0] = nss.read(); //represent byte 1
    vals[1] = nss.read(); //represent byte 2
    vals[2] = nss.read(); //represent byte 3
   
    heartRate = 0; // Sets all 8 bits to 0
    oxyLevel = 0; // Sets all 8 bits to 0

    bitWrite(heartRate, 0, bitRead(vals[1], 0)); // Set bit 0
    bitWrite(heartRate, 1, bitRead(vals[1], 1)); // Set bit 1
    bitWrite(heartRate, 2, bitRead(vals[1], 2)); // Set bit 2
    bitWrite(heartRate, 3, bitRead(vals[1], 3)); // Set bit 3
    bitWrite(heartRate, 4, bitRead(vals[1], 4)); // Set bit 4
    bitWrite(heartRate, 5, bitRead(vals[1], 5)); // Set bit 5
    bitWrite(heartRate, 6, bitRead(vals[1], 6)); // Set bit 6
    bitWrite(heartRate, 7, bitRead(vals[0], 0)); // Set bit 7
    bitWrite(heartRate, 8, bitRead(vals[0], 1)); // Set bit 8
     
    oxyLevel = vals[2];
  }
}

This program can be compiled. But i dont really understand it.

Can someone explain it to me in simpler terms? Thanks. :)







Groove

#1
Feb 18, 2011, 02:22 pm Last Edit: Feb 18, 2011, 02:48 pm by Groove Reason: 1
Which specific bit don't you understand?

Code: [Select]
byte vals[3];
int heartRate, oxyLevel;

There's no reason for these to have global scope.

Code: [Select]
Serial.print("Heart rate: ");
   Serial.println(heartRate);
   Serial.print("Oxygen level: ");
   Serial.println(oxyLevel);

Why print results before you've calculated them?

If you replace the "bitWrite"s with the following,
Code: [Select]
heartrate = (vals[1] & 0x7F) | ((vals [0] & 3) << 7);, is that any clearer?


Much simpler terms:
Code: [Select]
#include <NewSoftSerial.h>
NewSoftSerial nss(5,8);
void setup()
{
 nss.begin(9600);
 Serial.begin(9600);
}

void loop()
{
 if(nss.available() >= 3)
 {
   int heartRateMS = nss.read ();
   int heartRateLS = nss.read();
   int oxygenLevel = nss.read ();

   Serial.print("Heart rate: ");
   // heart rate is packed in bit 0..6 of heartRateLS and 0..1 of heartRateMS
   Serial.println((heartRateLS & 0x7F) | ((heartRateMS & 3) << 7));
   Serial.print("Oxygen level: ");
   Serial.println(oxygenLevel);
 }
}


When posting code, always remember to use the # (code) icon on the editor's toolbar, please.
Per Arduino ad Astra

robtillaart


The application reads 3 bytes from a serial device connected to pin 5 and 8.
This is a sensor that reads the heartrate and the oxygen level I assume based upon the variable names.

The number indicating the heartrate is divided over 2 bytes and the oxygen level is in the 3rd byte.

After extracting the heartrate and oxygenlevel from the bytes received, they are sent to the hardware serial port (USB),. Becuase there is explanationary text with it it is for human consumption.

The heartrate is 9 bits (0..511), (511 ? then you are pretty exited :)
The oxylevel is 8 bits (0..256) , presumably 0..100%

There is a BUG in your code in the sense that it first writes the value of heartbeat and oxy and then these vars are filled. In practice this will only result in a faulty value the first iteration of loop(). Groove solved this bug 100% (well done).

Question arises
- what sensor/device is connected to this sketch ? do you know?
- there is no timing control in this sketch, so how to interpret the output?


Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

moomoo

Guys, i really appreciate your help. Sorry that i am abit slow.
I am connecting an Arduino Pro Mini to the Nonin OEM III Module.
Module specs:
http://www.nonin.com/documents/OEM%20III%20Module%20Specifications.pdf (Look at Page 5 under Serial Data Format #1)

Allow me to clarify some doubts:
1.) byte vals[3]; refers to the 3 bytes (vals 0,1 and 2) that i will later extract the data from the 24 bits?

2.) if(nss.available() >= 3)  - i don't understand how this works.

3.) heartRate = 0; // Sets all 8 bits to 0
       oxyLevel = 0; // Sets all 8 bits to 0...........Is this necessary?

4.) bitWrite(heartRate, 7, bitRead(vals[0], 0));
     bitWrite(heartRate, 8, bitRead(vals[0], 1));...........bitRead reads bit 1 from vals[0] and bitWrite writes bit 1 into a numeric  variable 8?


Code: [Select]
#include <NewSoftSerial.h>
NewSoftSerial nss(5,8); // Put your TX and RX pins here, in the correct order

byte vals[3];
int heartRate, oxyLevel;

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

void loop()
{
  if(nss.available() >= 3)
  {
    vals[0] = nss.read(); //represent byte 1
    vals[1] = nss.read(); //represent byte 2
    vals[2] = nss.read(); //represent byte 3
   
    heartRate = 0; // Sets all 8 bits to 0
    oxyLevel = 0; // Sets all 8 bits to 0

    bitWrite(heartRate, 0, bitRead(vals[1], 0)); // Set bit 0
    bitWrite(heartRate, 1, bitRead(vals[1], 1)); // Set bit 1
    bitWrite(heartRate, 2, bitRead(vals[1], 2)); // Set bit 2
    bitWrite(heartRate, 3, bitRead(vals[1], 3)); // Set bit 3
    bitWrite(heartRate, 4, bitRead(vals[1], 4)); // Set bit 4
    bitWrite(heartRate, 5, bitRead(vals[1], 5)); // Set bit 5
    bitWrite(heartRate, 6, bitRead(vals[1], 6)); // Set bit 6
    bitWrite(heartRate, 7, bitRead(vals[0], 0)); // Set bit 7(Vals[0])
    bitWrite(heartRate, 8, bitRead(vals[0], 1)); // Set bit 8(Vals[0])
   
    bitWrite(oxyLevel, 0, bitRead(vals[2], 0)); // Set bit 0
    bitWrite(oxyLevel, 1, bitRead(vals[2], 1)); // Set bit 1
    bitWrite(oxyLevel, 2, bitRead(vals[2], 2)); // Set bit 2
    bitWrite(oxyLevel, 3, bitRead(vals[2], 3)); // Set bit 3
    bitWrite(oxyLevel, 4, bitRead(vals[2], 4)); // Set bit 4
    bitWrite(oxyLevel, 5, bitRead(vals[2], 5)); // Set bit 5
    bitWrite(oxyLevel, 6, bitRead(vals[2], 6)); // Set bit 6
   
    Serial.print("Heart rate: ");
    Serial.println(heartRate);
    Serial.print("Oxygen level: ");
    Serial.println(oxyLevel);
   
    delay (100); 
     
     
  }
}


I hope this is correct after looking at the module specs on page 5.  :)














         














Groove

#4
Feb 18, 2011, 11:26 pm Last Edit: Feb 18, 2011, 11:29 pm by Groove Reason: 1
Quote
1.) byte vals[3]; refers to the 3 bytes (vals 0,1 and 2) that i will later extract the data from the 24 bits?

2.) if(nss.available() >= 3)  - i don't understand how this works.

3.) heartRate = 0; // Sets all 8 bits to 0
      oxyLevel = 0; // Sets all 8 bits to 0...........Is this necessary?

4.) bitWrite(heartRate, 7, bitRead(vals[0], 0));
    bitWrite(heartRate, 8, bitRead(vals[0], 1));...........bitRead reads bit 1 from vals[0] and bitWrite writes bit 1 into a numeric  variable 8?



1) Ignore the fact that it is 24 bits. It is one 16 bit value (not really, more later), and one 8 bit value.
2) check to see if at least three characters have been received from the nss serial interface
3) Not necessary for oxyLevel, and not necessary for most of heartRate.
4)C doesn't allow variables with names that start with a numeric character, so a variable called 8 is not possible.

it read bit 1 from vals[0] and writes the value of that bit to bit 8 of the variable heartRate.

The code I wrote above is exactly equivalent to your originalcode.
Per Arduino ad Astra

moomoo

one character = one byte?
Quote
3) Not necessary for oxyLevel, and not necessary for most of heartRate.

means i can just remove those 2 statements? :)

Groove

No. Just one of them.
If you look at my rework, you don't need them at all.

Can you explain what it is you don't understand?
Is it how numbers are represented in binary?
How whole values or bits are assigned?
Per Arduino ad Astra

moomoo

Quote
[2.) if(nss.available() >= 3)  - i don't understand how this works./quote]
Code: [Select]
2) check to see if at least three characters have been received from the nss serial interface


does one character refer to one byte?

Quote
3) Not necessary for oxyLevel, and not necessary for most of heartRate.


I don't understand this quote..sorry.. :(

Groove

1) in this case yes,one character == one byte

2) You're going to write a whole new value in to oxyLevel, so setting it to zero is pointless.
In the case of heart-rate, you have an int variable, but you are using only 10 bits of the sixteen.
Normally, the other six would be undefined, so you would have to set them to zero.
However, because of how and where you have declared the heart-rate variable, the compiler has already initialised all sixteen bits to zero, so the siz unused bits will never be over-written, and the other ten will all be updated each time through the loop.
Per Arduino ad Astra

Go Up