Go Down

Topic: Assistance with sending and receiving a multiple byte integer over Serial1 (Read 1 time) previous topic - next topic

Seiryuu

Hello,

I need my program to send sharedindex as multiple bytes over Serial1, and read a value sent that way and assemble it again into a usable integer that I can use for operations again.

The full code I got is below. When executed, it doesn't seem like the key is actually being sent or assembled properly, othersharedIndex always gives me the same number in decimal which can't be correct.

Any and all assistance would be appreciated. I would appreciate general tips as well, I am very very new to this, as might be evident. It's a communication/encryption program.

Thank you in advance.

Code follows:

Code: [Select]

uint8_t key = 0;
uint32_t othersharedIndex = 0;
uint32_t sharedindex = 0;
uint32_t g = 16807;
uint32_t p = 2147483647;
uint32_t B = 0;

uint8_t get_seed()
{
 uint8_t seed = 0;
 for (int i=0; i<16; i++) {
   seed = seed << 1;
   seed = seed ^ analogRead(i);
 }
 return seed;
}

uint32_t mul_mod(uint32_t b, uint32_t e, uint32_t m) {

 uint32_t answer = 0;  //What we want to find out, 42
 uint32_t r = b; //local variable so we don't modify b outside of this thing.
 uint32_t a = e;
 while ( r ) {  

   if ( r & 1 ) {
     answer = ( answer + a ) % m;  
   }
   
     r = r >> 1;
   a = (a << 1) % m ;
 }
 return answer;
}

uint32_t pow_mod(uint32_t b, uint32_t e, uint32_t m) {

 
 // if b = 0 or m = 0 then result is always 0
 if ( b == 0 || m == 0 ) {
   return 0;
 }

 // if e = 0 then result is 1
 if ( e == 0 ) {
   return 1;
 }
 // Special cases ^
 // reduce b mod m
 uint32_t r = 1; // Our result.
 uint32_t redb = b % m;

 // stop the moment no bits left in e to be processed
 while (e){
   if ( e & 1 ) {
     r = mul_mod(r, redb, m);
   }

   // and we need to ensure that  r = (b ** e_[i..0] ) % m
   // is the current bit of e set?
   r = r;
   redb = mul_mod(redb, redb, m);
   //Repeats on the next power of b
   e = e >>1;
   // We shift to move things forward, when we have 0 left we are done.


 }

 // at this point r = (b ** e) % m, we don't overflow anymore!
 return r;
}

void readline(char *s, int bufsize){
 uint8_t i = 0;

 while( i < bufsize-1 ) {
   // wait for a character
   while (Serial.available() == 0) {
   } /* Do nothing */

   // grab the character and save in the buffer
   s[i] = Serial.read();

   // if end of line or somehow a \0 got sent, we are done
   if (s[i] == '\n' || s[i] == '\0') break;
   i += 1;
 }
 // \0 teminate the string
 s[i] = '\0';
}

/* readlong:

Read a sequence characters from the serial monitor and interpret
them as a decimal integer.

The characters can be leading and tailing blanks, a leading '-',
and the digits 0-9.

Return that number as a 32 bit int.
*/
int32_t readlong()
{
 char s[128]; /* 128 characters should be more than enough. */
 readline(s, 128);
 return atol(s);
}

void sendkey(uint32_t sharedindex) {
 if(Serial1.available()){
   // reads in a byte and shifts it over for the next byte
   Serial1.write( (sharedindex >> 24) & 0xFF );
   Serial1.write( (sharedindex >> 16) & 0xFF );
   Serial1.write( (sharedindex >> 8) & 0xFF );
   Serial1.write( sharedindex & 0xFF );
 }
}
//This breaks the key into bytes and sends it over

void setup()
{
 Serial.begin(9600);
 Serial1.begin(9600);
 randomSeed(get_seed());
 uint32_t a = random(256); //& 0xff ;
 // the & 0xff masks this from potential eavesdroppers by making our 8 bit key appear as a 32 bit one.

 Serial.println("This is my shared index a: ");
 //Serial.println(pow_mod(g, a, p)); //This displays shared index on my screen.
 sharedindex = (pow_mod(g, a, p));

 Serial.println(sharedindex);
 //delay(3000); //No need to rush, setup time for exchange.

 sendkey((uint32_t)sharedindex);
 //This sends the local Shared index, as bytes, to my partner.

 /*Serial1.write("Hello");
 
  if (Serial1.available()){
  int32_t inByte = Serial1.read();
  Serial.write(inByte);
  }
  */

 if (Serial1.available()){
   //uint32_t B = Serial1.read();
   //for(int i=0;i <=4; i++) super_data.read_byte[i]=Serial.read();
   othersharedIndex = othersharedIndex | Serial1.read() << 24;
   othersharedIndex = othersharedIndex | Serial1.read() << 16;
   othersharedIndex = othersharedIndex | Serial1.read() << 8;
   othersharedIndex = othersharedIndex | Serial1.read();
 }

 Serial.println("My partner's Shared Index is:");
 Serial.print (othersharedIndex, DEC);
 B = othersharedIndex;

 //Serial.println(B);

 othersharedIndex = (pow_mod(B, a, p));
 Serial.println(othersharedIndex);
 int16_t inByte = Serial1.read();
 Serial.write(inByte ^ othersharedIndex) ;
 uint8_t incomingByte = Serial.read();
 //uint32_t othersharedIndex = 0;
 Serial.print(othersharedIndex, DEC);






}

void loop()
{
 /*
 if (Serial1.available()){
  int32_t inByte = Serial1.read();
  Serial.write(inByte);
  }
  */
 //uint32_t go;
 //go = readlong();
 //Debugging, allows me to pause.Program wont advance till I hit enter
 /*
 Serial.println ("This is a:");  
  Serial.println(a);
  Debugging code
  */

 /*
 uint32_t b, e, m;
 
  b = readlong();
  Serial.print("b=");
  Serial.print(b);
  Serial.print(" ");
 
  e = readlong();
  Serial.print("e=");
  Serial.print(e);
  Serial.print(" ");
 
  m = readlong();
  Serial.print("m=");
  Serial.print(m);
  Serial.print("\n");
 
  Serial.print("answer = ");  
  Serial.println(pow_mod(b, e, m));
 
  Debugging code to test pow mod and mul mod functions (plug in number, power, mod, will display answer in serial.
  */
}











AWOL

Code: [Select]
 if(Serial1.available()){
   // reads in a byte and shifts it over for the next byte
   Serial1.write( (sharedindex >> 24) & 0xFF );

Not sure what's going on there - the comment doesn't seem to cover it.

Code: [Select]
if (Serial1.available()){
   //uint32_t B = Serial1.read();
   //for(int i=0;i <=4; i++) super_data.read_byte[i]=Serial.read();
   othersharedIndex = othersharedIndex | Serial1.read() << 24;
   othersharedIndex = othersharedIndex | Serial1.read() << 16;
   othersharedIndex = othersharedIndex | Serial1.read() << 8;
   othersharedIndex = othersharedIndex | Serial1.read();


Ah! The usual.
See if there is one byte available, then go ahead and read all four of them.

Good job we found this before the sketch grew too big.
"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.

Seiryuu


Code: [Select]
 if(Serial1.available()){
   // reads in a byte and shifts it over for the next byte
   Serial1.write( (sharedindex >> 24) & 0xFF );

Not sure what's going on there - the comment doesn't seem to cover it.

That's my code for sending the key. It may be where the problem is.

What I'm trying to do is divide a 32 bit integer into bytes and send the bytes one at a time by sending parts of the integer as a bite, then bit shifting and sending again.

It might be (likely is) wrong, I am fairly new to this, but I put that together from the documentation and thought it might work.


AWOL

The "available" method relates to received characters, and has nothing at all to do with transmitted values.
"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.

Seiryuu

Read your post and changed it to

Code: [Select]
if (Serial1.available() == 4){
   
   othersharedIndex = othersharedIndex | Serial1.read() << 24;
   othersharedIndex = othersharedIndex | Serial1.read() << 16;
   othersharedIndex = othersharedIndex | Serial1.read() << 8;
   othersharedIndex = othersharedIndex | Serial1.read();
 }


But I might be wrong, the output of the program is this:

Quote
This is my shared index a:
1962408013
My partner's Shared Index is:
00
ΓΏ0


Edit: Also, thank you for taking the time to help me, I am really lost at the moment.

AWOL

There's a potential problem with that code - what if there happen to be five bytes available to read when you first look?
"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.

Seiryuu

Good point.

What is a good way to fix it? I tried bigger than 0 and smaller than 5 and that didn't seem to work. The only times I get an actual number value, its always the same number value, so I am thinking that its an error of some sort.

I think I am sending the key wrong. I am thinking the way I have it set up, I send the key long before there is anything listening to receive it. Tried moving sendkey((uint32_t)sharedindex); to the loop and it didn't work either, though.

I figured where the gibberish was coming from, it was the random print calls I had later to debug.

Moved the Serial.println("My partner's Shared Index is:"); line inside of the if (Serial1.available() == 4){ listening part, and it is not printing at all which makes me think that part of the code is not running at all.

Any suggestions/solutions? And again, thanks, I really appreciate this, have been working on it all night (rather, all week, finally figured to ask in the forum, I can't seem to figure it out no matter what I try).

AWOL

I hinted above that your sketch was too big.
You should write only the code to reliably transmit and receive unsigned long numbers.
When you've got that working, pile all the other stuff back in.

Building anything on shaky foundations is always a recipe for hair-loss.

Quote
I tried bigger than 0 and smaller than 5 and that didn't seem to work. T

How about "at least four" ?
Of course, you have no means of knowing that you haven't mixed one byte from one number with three from another, but that's a different issue.
If you send you numbers infrequently, you stand a better chance of staying in sync.
"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.

Seiryuu


I hinted above that your sketch was too big.
You should write only the code to reliably transmit and receive unsigned long numbers.
When you've got that working, pile all the other stuff back in.

Building anything on shaky foundations is always a recipe for hair-loss.


Will do.

I really have no idea how to get the code to reliably transmit and receive unsigned long numbers working, however.

Any good resources that might help someone with barely any clue of what they are doing? Google only gave me an instructable that didn't work, and I think I have gotten as far as the documentation on the arduino site is going to take me. I have a copy of my partner's code, but he doesn't have that part working either, and his powers function doesn't work either (fixed that one).

I am new to coding (this is for a computing science 100 class, which works under the full collaboration model and encourages us to try to get assistance/work in teams/google) and I am... well, really frustrated with this.

I am hoping its something simple, but whether its simple or not, I can't really see it because I really don't have the background or understanding of how all this works.

I don't mean to come off as whiny, and I really appreciate your assistance.

Seiryuu

Tried this:

Code: [Select]
uint32_t keylisten = 1;

  if (Serial1.available() > 0){
    while (keylisten = 1){
      sendkey((uint32_t)sharedindex);
       if (Serial1.available() >= 4){
        othersharedIndex = othersharedIndex | Serial1.read() << 24;
        othersharedIndex = othersharedIndex | Serial1.read() << 16;
        othersharedIndex = othersharedIndex | Serial1.read() << 8;
        othersharedIndex = othersharedIndex | Serial1.read();
        Serial.println("My partner's Shared Index is:");
        keylisten = 0;
       }
  }
  }


I think my problem is (probably) in the receiving and perhaps what I need is a loop that keeps sending until someone has the answer (at this point I only need it to be able to talk to itself over Serial1)

It didn't work (nothing at all displays in monitor, so its still not getting the 4 bytes to move on to printing the shared index)

AWOL

Code: [Select]
while (keylisten = 1)
That's always going to cause a problem.

(Heavy emphasis on "always")
"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.

Seiryuu

Yeah, I realized that after I read your post and while I was in the process of asking why (because im defining it as 1 every time so it'll be stuck there forever)

Changed it to while (keylisten == 1), which should make the exit condition possible?

It doesn't matter too much. Its 6 in the morning and I couldn't get this to work. Trying to google up more stuff on how exactly communication works, but I can't figure out what the problem is (well, I know what the problem is, it doesn't work, but I don't have a clue why).

The while loop didn't work either.

I don't know if I'm sending wrong, or listening wrong, or if im completely off base with now trying to use a loop but I'm at the point where I can't think anymore, and I can't find an answer online either, so I'm thinking its something really simple.

But try as I might, I can't see it.

Made a barebones sketch with just those parts, and I can't get the Arduino to listen and succesfully transmit/receive a multiple byte number.

I have no problem with communication using the monitor however.

Thank you for your help so far.

Arrch


Made a barebones sketch with just those parts, and I can't get the Arduino to listen and succesfully transmit/receive a multiple byte number.

How about posting that, and we can see if it is in fact, a simple error?

AWOL

Very simple transmitter (uncompiled, untested)
Code: [Select]
void transmit (unsigned long txVal)
{
  for (int i = 0; i < 4; ++i, txVal >> = 8)
  {
    Serial.write ((byte)(txVal & 0xFF));
  }
}
"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