Go Down

Topic: Sending large values using Wire.send() (Read 3024 times) previous topic - next topic

tgregor

Quote
Going above 4 will be scary since the arduino does not support datatyes above 4 bytes.


I'm guessing that the number 2828601 is above 4 bytes? because I can't get it to send properly it will send all but 4 bits of data
this is what I get:
2828601=1010110010100100111001
it will get: 101011    101001  111001

I don't get why its those bits in between. for the code all i'm having it do is print out the buffer array each cell at a time. any ideas, is this even possible to send?

rFree

There is "long long" introduced in C99 that is required to be at least 64 bits wide.

Serial.println(sizeof(long long)); seems to confirm it's availability in arduino.

retrolefty

Is "long long" type really avalible in the Arduino system? It's not listed in the Arduino reference data types.

Lefty


rFree

Certainly seems like it.

Code: [Select]
void setup()
{
   Serial.begin(9600);
   delay(100);
}

void loop()
{
   long long x;
   Serial.println(sizeof x);
}

tgregor

I cant figure this out. I have to be able to send a value as large as 9999999 but the formating keeps changing and I don't know what to do from here.  This is my sending code:
Code: [Select]
#include <Wire.h>
#define buzz 11
#define master 1



void setup(){
 Serial.begin(9600);
 Wire.begin(1);
 Wire.onReceive(inp);
// sendData();
}


void loop(){
long long user=4638671;
  byte* pInt=(byte*) &user;
 
  Wire.beginTransmission(2);
  Wire.send(pInt,sizeof(user));
  Wire.endTransmission();
/*
 Wire.beginTransmission(2);
   Wire.send(pInt,sizeof(user));
 Wire.endTransmission();
 */
 delay(5000);
}

void inp(int count){
 int x = Wire.receive();
 Serial.println(x);
 
}


And this is my receiver code:
Code: [Select]
#include <Wire.h>
#define address 2
#define green 13

int inputCount=0;
long long result=0;
//int x=0;
void setup(){
 Serial.begin(9600);
 Serial.println("ready");
 Wire.begin(2);
 Wire.onReceive(test);
 pinMode(green,OUTPUT);
}
 
void loop(){
}

void test(int sizeIn){
 Serial.println(sizeIn);
 int buffer[sizeIn];
while(Wire.available()){
buffer[inputCount]=Wire.receive();
inputCount++;
 //Serial.println(buffer[inputCount]);
}
 switch(inputCount){
   case 1:
   result = buffer[0];
   break;
   case 2:
   result = buffer[1]<<8*1|buffer[0]<<8*0;
   break;
   case 3:
   result =buffer[2]<<8*2|buffer[1]<<8*1|buffer[0]<<8*0;
   break;
   case 8:
   result= buffer[2]<<16 | buffer[1]<<8 | buffer[0];
   Serial.println(result,BIN);
   //Serial.println(result);
   Serial.println(buffer[0],BIN);
   Serial.println(buffer[1],BIN);
   Serial.println(buffer[2],BIN);
   Serial.println(buffer[3],BIN);
   break;
 }
  //Serial.println(result);
  inputCount=0;
  result=0;

}


I succeeded in getting it to send numbers of the size #### but this is getting more and more complicated and i'm getting more and more confused.  any ideas on how to make this simpler? can it be simpler? or does it need to be more complicated?

AWOL

#20
Jun 17, 2009, 08:34 am Last Edit: Jun 17, 2009, 09:01 am by AWOL Reason: 1
Quote
a value as large as 9999999


A range of only 10 million doesn't need a "long long".
An ordinary signed long (32 bits) covers the range -2147483648 to +2147483647 decimal.
An unsigned long will cover 0..4294967296 decimal.

Code: [Select]
void test(int sizeIn){


What is the value of "sizeIn"? Where does it come from?

I don't see why you don't just have a fixed-size receiver buffer, bit enough to contain a single "long".
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

tgregor

Code: [Select]
void test(int sizeIn)
This is the function that is called when the arduino starts receiving data.
Code: [Select]
Wire.onReceive(test);

I think the reason I didn't use a long buffer is that because the number length may not always be a long. Is that even a problem? Also I'm not sure how I would go about doing that.  Is that what I was doing?

Is there a way i can just send the digits one at a time and then reassemble them, that seems like it would be the easiest.

AWOL

Quote
This is the function that is called when the arduino starts receiving data


So, each time it gets called, you potentially have a different value of "sizeIn", but you're declaring "buffer" based on that size...see where this is going?
"buffer" isn't static.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

tgregor

the buffer doesn't seem to be working properly. I still don't understand this error.
2828601=1010110010100100111001
it will get: 101011    101001  111001

Why is it (dropping?) or not receiving those zeros in between? is it because they are leading zeros and they get truncated off because it assumes that the zeros are irrelevant? can I fix this, but if i fix this how will it change other values? because I've gotten it to successfully send some numbers of the same length but this zero problem would change everything. i think the most reliable way would be to send it bit by bit but I don't know how to do that.

AWOL

Quote
the buffer doesn't seem to be working properly. I


Change the declaration to:
"static byte buffer [8];"

and try again.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

AlphaBeta

#25
Jun 17, 2009, 07:20 pm Last Edit: Jun 17, 2009, 07:22 pm by AlphaBeta Reason: 1
This code uses the binary values you posted and builds the correct number:

Quote

void setup(){
 Serial.begin(9600);
 byte original[] = {B111001,B101001,B101011,B0};
 
 unsigned long target = 0;
 byte* targetWorker = (byte*)&target;
 
 targetWorker[0] = original[0];
 targetWorker[1] = original[1];
 targetWorker[2] = original[2];
 targetWorker[3] = original[3];
 
 Serial.println(target);
}

void loop(){
}


[edit]
Quote
is it because they are leading zeros and they get truncated off because it assumes that the zeros are irrelevant?

This is correct.

(Irrelevant for print, relevant for bit shifting/reconstruction.)[/edit]

tgregor

I think that might give me a bit to work with to try to figure this out, The only issue I see is that the value i'm sending will change. The value is coming from a RFID reader.

AWOL

Please, think seriously about this:
Code: [Select]
void test(int sizeIn){
 Serial.println(sizeIn);
 int buffer[sizeIn];


It may work now, but there are no guarantees for the future.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

tgregor

I think I got it!

here is the sender code:
Quote


#include <Wire.h>
#define buzz 11
#define master 1
void setup(){
 Serial.begin(9600);
 Wire.begin(1);
 Wire.onReceive(inp);
 // sendData();
}
void loop(){
 long user=1696;
 byte* pInt=(byte*) &user;
 Wire.beginTransmission(2);
 Wire.send(pInt,sizeof(user));
 Wire.endTransmission();
 /*
 Wire.beginTransmission(2);
  Wire.send(pInt,sizeof(user));
  Wire.endTransmission();
  */
 delay(5000);
}
void inp(int count){
 int x = Wire.receive();
 Serial.println(x);
}
void sendData(){
}


And here is the receiver code:

Quote


#include <Wire.h>
#define address 2
#define green 13

int inputCount=0;
unsigned long user=0;
void setup(){
 Serial.begin(9600);
 Serial.println("ready");
 Wire.begin(2);
 Wire.onReceive(test);
 pinMode(green,OUTPUT);
}

void loop(){
}

void test(int sizeIn){
 inputCount=0;
 byte buffer[sizeIn];
 while(Wire.available()){
   buffer[inputCount]=Wire.receive();
   inputCount++;
 }
 byte* targetWorker = (byte*)&user;

 for(int i=0;i<=sizeIn;i++){
   targetWorker = buffer;
 }
 Serial.println(user);
}


Is there a way to have the sender send it to all  many different receiver devices? Or do I have to just have it loop through all of the addresses and send them one at a time?

AWOL

I'm sorry, I'm still not getting this bit:

Code: [Select]
void test(int sizeIn){
inputCount=0;
byte buffer[sizeIn];
while(Wire.available()){
  buffer[inputCount]=Wire.receive();
  inputCount++;
}
byte* targetWorker = (byte*)&user;

for(int i=0;i<=sizeIn;i++){
  targetWorker[i] = buffer[i];
}
Serial.println(user);
}


Suppose that "test" gets called with "sizeIn" = 1, because the receiver has only received one byte. So, "buffer" is allocated 1 byte.
Now, it's quite possible that by the time the "while" loop has read that single character, the next one has arrived, so "available" is true, and that character is read.
In fact, looking at the code, this is the only way this can work, unless "test" is always called with the value "4" for "sizeIn" - "test" has to read all four bytes in one hit, otherwise the byte-by-byte assignment to "targetWorker" will fail.

But "buffer" was only allocated one byte.

Can you confirm the value of "sizeIn"?

This strikes me as a real ass-biter - anyone?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up