0

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 x.b = val1 | (val2<<8); Serial.print(x.a.page); 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.

dda
  • 6,030
  • 2
  • 25
  • 34
patatos
  • 23
  • 1
  • 8
  • Now I see I can't make any correction in the code. :( – patatos Aug 11 '17 at 06:19
  • Now I see why my shared code is wacky. I can't make any correction in the code. :( , because I was doing TAB accidentally that send the code directly, and even if I come back to the code I can't modify it. I should have be aware. Apologies. – patatos Aug 11 '17 at 06:34

3 Answers3

0

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

0___________
  • 60,014
  • 4
  • 34
  • 74
  • Thank you, but I am very troubled. I can not find a conterfact that the member's value of a struct in union is conserved, as long as an union is volatile. Does not it be the contrary? What I am missing? – patatos Aug 10 '17 at 22:50
  • If there are no side effects ie. all potential changes to the object are "visible" to the compiler during compilation it is not necessary, and the compiler will take care of it. If object may be changed by something where is no execution path - for example in the interrupt routine, hardware registers, shared memory etc etc you must declare it as volatile. – 0___________ Aug 10 '17 at 22:55
  • Please, don't take point of the precedent message. Thank you PerterJ! I'll coming back. EDIT: wow, so fast. Sorry for the mess, and thank you for putting words on my guesses. – patatos Aug 10 '17 at 22:58
  • PeterJ, please let me return to your addendum," you need to write MegaUnion.val1 = 1 or MegaUnion.val_table[0] = 1 or MegaUnion.b = 1". I would rather use a boucle while on a subsript for the best attempt, but is it possible? Or at least a switch case? Thank you – patatos Aug 11 '17 at 21:18
  • I do not undestand. It does not matter. No swich or if needed. `MegaUnion.val1 = 1 or MegaUnion.val_table[0] = 1` `MegaUnion.val2 = 1 or MegaUnion.val_table[1] = 1` mean the same .b is 16 bit value which covers the both – 0___________ Aug 11 '17 at 21:27
0

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.

Nick Gammon
  • 1,173
  • 10
  • 22
  • I am very sorry, I don't know why I wrote that. Was the temporary. This is the good one: – patatos Aug 11 '17 at 02:47
  • I can't post it. I don't know how. Sorry. Should I use another question? – patatos Aug 11 '17 at 02:49
  • What can't you post? You can edit the question if necessary to clarify. – Nick Gammon Aug 11 '17 at 02:58
  • I edited the post, I wasn't sure I could do it directly. Thank you! – patatos Aug 11 '17 at 04:42
  • For Nick Gammon: 1/ Yes, true, I forgot to show my flag after 4 Serial.read. 2/ I corrected this point in the post 3/ thanks for the master's tip, If you wouldn't mind to describe, and how to access the interrupt service routine, that would be great! – patatos Aug 11 '17 at 04:56
  • See amended reply. I suggest doing some C tutorials - I think you will find them useful. – Nick Gammon Aug 11 '17 at 05:14
  • I tried to modify this "coquille", impossible. This is not an personnal code error, but a misunderstanding about the editing concept here. It's more kind of tweeter concept. Impossible to return to the code after a TAB press. I tried to use TAB as replacement of the 4 spaces. And before understand the trick, I send several codes modified that never shown on the site. I surely have habit! I will do my best to stick with your working methods. Thank you – patatos Aug 11 '17 at 20:31
  • @patatos - please do not keep attempting to reply by editing my answer. Editing answers is for fixing typos, or adding additional information. It is not for the person asking the question to ask more questions. Use comments for that. – Nick Gammon Aug 11 '17 at 21:11
  • Understood. Thank you Nick Gammon. – patatos Aug 11 '17 at 21:23
0

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.

patatos
  • 23
  • 1
  • 8