简体   繁体   中英

Arduino Uno - serial.read to a struct of bits

This question is following this post: arduino - how to feed a struct from a serial.read()

First I would like to thank Sol Arnu for his previous code I am showing below. Please note the code is efficient. So far the best try. Even if I don't think any bit is sent to the table. Now I can print a "1". However if I change the page sent (2 instead of 1), there is no change. This part xb = val1 | (val2<<8); Serial.print(xapage); xb = val1 | (val2<<8); Serial.print(xapage); is confusing for me. Does it compare 2 var bits and places the result in an instance of a struct by a union?

I didn't say it's an Arduino Uno (8 bits, memory and register). Can you see what's happening?

#include <SoftwareSerial.h>
#define PACKED __attribute__((__packed__))

SoftwareSerial PORTone(8, 9); // port 1
SoftwareSerial PORTtwo(10, 11); // port 2

PACKED union {
  PACKED struct {
unsigned int val1:
    1; // (0,1)
unsigned int val2:
    4; // 10 choices (4 bits)
unsigned int val3:
    3; // 5 choices (3 bits)
unsigned int val4:
    2; // 3 choices (2 bits)
  }
  *PtrStr;
  uint8_t  val_table[2];
  uint16_t b;
}
*MegaUnion;

//*********************************SETUP***************
void setup() {
  Serial.begin(9600);
  PORTone.begin(9600);
}

//**********************************LOOP***************
void loop() {
  while(PORTone.available()>0) {
    delay(100);
    for(int i = 0; i<=4; i++) {    
      for(int i = 0; i<=3; i++) {  
        for( int j = 0; j<=3; j++) {
          int inByte = PORTone.read();         
          *MegaUnion.struct.val1[j] = inByte; // error: 'union<anonymous>' has no member named 'val1'
        }
        //  I should that too
        //  u_structTable x;
        //  x.b = val1 | (val2<<8);
        //  Serial.print(x.a.page); 
      }  
    } 
    // what is coming from the table
    Serial.print( (*MegaUnion).page);
  }
}

I should answer to Michaël Roy, (hopefully I can pass by this second thread). Thank you for your valuable answer. This seems to be another way I will test.

"EDIT" I also corrected a big mistake, nicely found by Nick Gammon, in order to give a better view of the subject. My bad.

Maybe this this union covers all types and as it uses anonymous structures less dots needed :) :

#define PACKED __attribute__((__packed__))

PACKED union {
    PACKED struct
    {
        unsigned int page:1; // (0,1)
        unsigned int cric:4; // 10 choices (4 bits)
        unsigned int crac:3; // 5 choices (3 bits)
        unsigned int croc:2; // 3 choices (2 bits)
    };
    PACKED struct
    {
        uint8_t val1;
        uint8_t val2;
    };
    uint8_t  val_table[2];
    uint16_t b;
}MegaUnion;

MegaUnion.val1 = PORTone.read();
MegaUnion.val2 = PORTone.read();

Remember that your page bitfield occupies the youngest bit of the union so to set it to one you need to write MegaUnion.val1 = 1 or MegaUnion.val_table[0] = 1 or MegaUnion.b = 1

Original code:

while(PORTone.available()>0) {
    volatile unsigned int val1, val2, val3, val4;
    for(int i = 0; i<=4; i++){    
        val1 = PORTone.read();
        val2 = PORTone.read();
        val3 = PORTone.read();
        val4 = PORTone.read();
    }
  • PORTone.available()>0 guarantees that a single byte is available for reading. You are reading 20 bytes. Almost certainly 19 of those will be -1 (0xFFFF).

  • I don't see why you are reading the four values five times.

  • There is no need to make val1, val2, val3, and val4 volatile because they are not being shared with an interrupt service routine.


Amended code:

while(PORTone.available()>0) {
delay(100);      
  for(int i = 0; i<=4; i++){    
      for(int i = 0; i<=3; i++){  
        for( int j = 0; j<=3; j++) {
          int inByte = PORTone.read();         
          *MegaUnion.struct.val1[j] = inByte; 

I don't see what you are doing here, except throwing stuff together and hoping for the best. You are now reading 80 bytes in the inner loop once you find a single byte available. The word "struct" doesn't belong there in the variable name. You have two loop variables, both called i .


If you wouldn't mind to describe, and how to access the interrupt service routine, that would be great!

What interrupt service routine? You don't need volatile unless you are using interrupts, which you don't seem to be doing.

As I only experienced so far, a struct member may not get his value by a var. Anyway, as long as I receive and a share (10 bits), no need to play with a struct. A string of 4 words should suffice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM