Go Down

Topic: Seriale con pochi bit (Read 2707 times) previous topic - next topic

erpomata

Una cosa del genere per il trasmettitore:

Code: [Select]

int pin4 = digitalRead(4) * 1;
int pin5 = digitalRead(5) * 2;
int pin6 = digitalRead(6) * 4;

int toSend = pin4 + pin5 + pin6;


oppure come dice leo:

Code: [Select]

byte toSend = 0;

if ( digitalRead(4) == HIGH )
bitSet(toSend, 0);

if ( digitalRead(5) == HIGH )
bitSet(toSend, 1);

if ( digitalRead(6) == HIGH )
bitSet(toSend, 2);

astrobeed


Una cosa del genere per il trasmettitore:

Code: [Select]

int pin4 = digitalRead(4) * 1;
int pin5 = digitalRead(5) * 2;
int pin6 = digitalRead(6) * 4;

int toSend = pin4 + pin5 + pin6;



Esatto.
Usare il GOTO in C è ammettere la propria sconfitta come programmatore

erpomata

Ok ora devo capire come decodificare  :smiley-sad-blue:

erpomata

#18
Oct 22, 2012, 04:02 pm Last Edit: Oct 22, 2012, 04:27 pm by erpomata Reason: 1
Quindi dovrebbe essere una cosa del genere:

Code: [Select]

byte input=7;    // input da seriale

int pin4 = input % 2;
int next = input / 2;

int pin5 = next % 2;
next = next /2;

int pin6 = next % 2;

digitalWrite(4, pin4):
digitalWrite(5, pin5):
digitalWrite(6, pin6):


o nella versione di leo:

Code: [Select]

byte input = 7; // input da seriale

digitalWrite(4, bitRead(input, 0)):
digitalWrite(5, bitRead(input, 1)):
digitalWrite(6, bitRead(input, 2)):



erpomata

Speravo in una conferma/smentita  =(

uwefed

non ho capito, vuoi una conferma o una smentita   ;) ;) ;) ;)

Sul serio: sí é giusto.
Ciao Uwe

PaoloP


lesto

il miglior sistema che ho trovato per comprimre i dati nel minor numero di byte è il seguente:
conta il numero di simboli che ti servono, mettiamo che hai 3 valori da inviare, con un numero di simboli ognuno A, B e C

a questo punto moltiplichi la variabile per il numero di simboli elevato alla posizione relativa
esempio:
val1*A^0+val2*B^1+val3*C^2 etc..

per smontare invece devi usare un ciclo, ed estrarre i valori al contrario attraverso delle divisioni.

ma se ti servono esattamente 4bit, e per non impazzire con la mateatica (e perder cicli macchina, il sismetema precedente è assai lento) allora tanto vale che ogni Write sulla serial unisci due letture

edit: rileggendo le risposte, la prima soluzione è una generalizzazione del sistema proposto da astro
Quote
In pratica non devi fare altro che leggere lo stato dei pin, moltiplicarlo per 1, 2, 4  a seconda del pin e sommare questi valori tra loro, il valore ottenuto è il byte da inviare, in ricezione devi fare il procedimento opposto.
, che dire, mi frega sempre :)
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

erpomata

Infatti mi sto orientando su quello ma, per ora, non ho avuto il tempo di farlo.

Grazie a tutti

astrobeed


il miglior sistema che ho trovato per comprimre i dati nel minor numero di byte è il seguente:


Il sistema migliore in assoluto è utilizzare una union, sia in ricezione che in trasmissione, però se non le conosce è inutile confondergli le idee.
Usare il GOTO in C è ammettere la propria sconfitta come programmatore

lesto

se mi link qualcosa sono interessato, trovo solo union del C, ma direi che centrano poco visto
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

erpomata

nono posta, tanto ora il meccanismo l'ho capito.
considerando che era roba di scuola e l'ho dovuta rispolverare è stato abbastanza semplice.

astrobeed

Le unioni, come le strutture, sono uno strumento del C che permette di creare nuovi tipi dati partendo dai tipi standard, nel nostro caso serve una unione che contiene un unsigned char e una struttura bitfield.

Code: [Select]


// definizione della struttura
union RTX_b
{
unsigned char RTByte;
struct PinStato
{
   unsigned char Bit1:1;
   unsigned char Bit2:1;
   unsigned char Bit3:1;
   unsigned char Bit4:1;
   unsigned char Bit5:1;
   unsigned char Bit6:1;
   unsigned char Bit7:1;
   unsigned char Bit8:1;
 } Bits;
} RTX_data;

void setup() {
  Serial.begin(9600);

 RTX_data.Bits.Bit1 = 1;
 RTX_data.Bits.Bit2 = 0;
 RTX_data.Bits.Bit3 = 1;
 RTX_data.Bits.Bit4 = 1;
 
 Serial.println(RTX_data.RTByte, DEC);
 
}

void loop()
{
}


Nel codice di esempio creiamo la unione RTX_b che contiene un unsigned char RTByte e una struttura bitfield PinStato, assegnando i vari bit alla struttura, ovvero i utilizzando i nomi  RTX_data.Bits.Bitx ove x è un numero da 1 a 8 che identifica i bit, setto singolarmente i singoli bit che compongono RTByte, la cosa è bidirezionale perché se carico un valore su RTByte i singoli  RTX_data.Bits.Bitx vengono posti a 1 o 0 in accordo con la codifica in binario del numero.
In pratica sulla parte trasmittente basta assegnare il valore letto da un pin a  RTX_data.Bits.Bitx, fino a otto pin diversi, e poi inviare sulla seriale RTX_data.RTByte, sulla parte ricevente basta copiare il valore ricevuto su RTX_data.RTByte e assegnare ai pin i valori dei RTX_data.Bits.Bitx.
Il tutto viene tradotto in una manciata di righe assembly che richiedono pochissimi cicli macchina.
Usare il GOTO in C è ammettere la propria sconfitta come programmatore

lesto

lavorare con il sistema di potenze o con le union è la stessa cosa (a livello di uso di memoria) se i valori validi sono solo 2 o potenze, ma non nel caso di altri numeri arbitrari. Però in questi casi "speciali" la union è sicuramente molto più performante a livello di calcolo
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

erpomata

Fico.
Comodissimo.

Grazie mille.

Go Up