system
November 15, 2010, 10:37pm
1
Hi, i want to use arduino for reading power value from the ttl port of a power meter that i've purchased, i'm using this code:
#include <NewSoftSerial.h>
NewSoftSerial dev(2,3);
void setup(){
dev.begin(115200);
Serial.begin(115200);
}
void loop(){
send:
dev.print('A'); //this is the power request
delay(1000);
while(dev.available()<5){
goto send;
}
int readed=0;
for(int i=0; i<4; i++){
readed = readed|(dev.read()<<(8*i));
}
dev.read();
Serial.println(readed, BIN);
delay(1000);
}
the problem is that i recive wrong values like those:
11111111111111111000000011000011
11111111111111111000000011000010
11111111111111111000000010110111
11111111111111111000000011000001
what i can do??
where is the problem?
thanx.
the problem is that i recive wrong values
What values were you expecting?
What are the specs for this meter?
Rob
system
November 16, 2010, 12:55am
3
You are using a horrible goto loop to send 'A' over and over until you get 5 bytes to read. Then, you read and save 4 of them, and then throw the 5th one away. Why?
How do you know you are getting wrong values. Does the fact that you don't get the number you expect have anything to do with the fact that you are trying to store 32 bytes in a 16 byte integer?
system
November 16, 2010, 7:31am
4
I've to recive 4 byte rappresenting the power value from the less significative, then i recive another byte wich is the checksum.
i use this goto loop to ensure that the power meter has recived the call, with a single request sometimes it don't respond
system
November 16, 2010, 7:38am
5
the meter comunicate via TTL with a baud rate of 115200.
I expected to recive a number like
00000000 00000000 00000000 10101110
After your :-
Serial.println(readed, BIN);
put a :-
Serial.println(" ");
to separate your bytes.
However it does look like your number is upside down (0 -> 1 and 1 -> 0), can you check the TTL levels from your meter and see which way up they are supposed to be.
system
November 16, 2010, 1:31pm
7
You still can't stuff 32 bits in a 16 bit variable. This MUST be the first problem you resolve.
That 'while...goto'.
It has to go.
It's just....wrong :-?
Removal of the goto by returning from loop() (just one of the possible ways)
void loop(){
...
if (dev.available() < 5) return;
...
}
Try reading things ONLY if you have enough data in the buffer.
void loop(){
dev.print('A'); //this is the power request
delay(1000);
if(dev.available()>=5){
int readed=0;
for(int i=0; i<4; i++){
Serial.print(dev.read(), BIN);
Serial.print(" ");
}
Serial.println(" ");
delay(1000);
}
}
system
November 16, 2010, 4:03pm
11
ok i've deleted the goto loop and created a more readable code
void loop(){
dev.print('A');
delay(1000);
word readed=0;
if(dev.available()>=5){
for(int i=0; i<4; i++){
readed = readed|(dev.read()<<(8*i));
}
dev.read();
Serial.println(readed, BIN);
Serial.println(readed);
delay(1000);
}
}
but the problem is that i get uncorrect values like those:
1000000010111001
32953
1000000010111001
32953
1100000010111001
49337
when the real power is about 100W
system
November 16, 2010, 4:08pm
12
is possible that the "newsoftwareserial" library has problem on the read function?
How many times do you want telling:-
for(int i=0; i<4; i++){
readed = readed|(dev.read()<<(8*i));
}
YOU CAN"T DO THAT!!! there are only 2 (TWO) bytes in an int.
system
November 16, 2010, 5:09pm
15
is this ok?
void loop(){
dev.print('A');
delay(1000);
unsigned long readed=0;
if(dev.available()>=5){
for(int i=0; i<4; i++){
readed = readed|(dev.read()<<(8*i));
}
Serial.print("Checsum= ");
Serial.println(dev.read());
Serial.println(readed, BIN);
Serial.println(readed);
delay(1000);
}
}
but the problem persist:
Checsum= 191
11111111111111111000000010111111
4294934719
Checsum= 191
11111111111111111000000010111111
4294934719
Checsum= 191
11111111111111111000000010111111
4294934719
system
November 16, 2010, 9:16pm
16
The NewSoftSerial constructor has an optional 3rd argument, to invert the data coming in. Perhaps you need to find out what value to use, and use it.
readed = readed|(dev.read()<<(8*i));
Why are you using |? After zeroing out the variable, you want to add the shifted value, don't you?
system
November 16, 2010, 9:42pm
17
i'm using | because i've to add every time the morst significant byte, maintaining the bytes previously written
Like:
read: 01001111
readed=00000000 00000000 00000000 01001111
read:00000010
readed=00000000 00000000 00000010 01001111
... four times
the ttl port of a power meter that i've purchased,
Do you have a datasheet / type info of the powermeter to better understand what you are communicating with.
system
November 17, 2010, 12:33am
19
Each byte you read in is being shifted 0, 8, 16, or 24 bits before being OR'd with the other values. Since you initially set the value to 0, all 32 bits are 0. Shifting the byte to be incorporated means that it will only affect 8 bits if you ADD it.