Sari la conținut
ELFORUM - Forumul electronistilor

Arduino: Hexadecimal


Vizitator

Postări Recomandate

Am o intrebare legata de notarea in HEX in codurile noastre. In linii mari, as vrea sa stiu, de ce se foloseste uneori HEX in loc de decimal. E doar o chestie de marele Guru, sau cu adevarat face diferente?

 

Sa presupunem acest cod exemplificativ de pe net, citire senzor DS18S20

#include <OneWire.h> 
 byte DS18S20_address[8] = {0x28, 0x1F, 0xF1, 0x43, 0x7, 0x0, 0x0, 0x18};
 int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2
 OneWire ds(DS18S20_Pin);

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

void loop() {
  float temperature1 = getTemp(DS18S20_address,0.0); 
  
  Serial.print("temperature:"); Serial.println(temperature1);
  Serial.println();
  delay(500); //just here to slow down the output so it is easier to read
}


double getTemp(byte *_addr, float adjust){
  //returns the temperature from one DS18S20 in DEG Celsius
  byte data[12];
  byte addr[8];
  
  for (int i = 0; i < 9; i++) {
    addr[i] = _addr[i];
  }  
  

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end
  
  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad

  
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = (tempRead / 16)+adjust;          
  return TemperatureSum;  
}

Asa cum spuneam, de ce apare notare in HEX , si cat de importanta este ?

Exemple: {0x28, 0x1F, 0xF1, 0x43, 0x7, 0x0, 0x0, 0x18} , ds.write(0xBE); .....etc,s.a.m.d

 

 

Topicul se incheie aici, in continuare este o anexa la acest TOPIC.

 

 

 

 

 

Nota

In alta ordine de idei, acest cod nu prea mi-a functionat, adesea senzorul DS18S20 trimite temperaturi aiurea. Evident este o problema de comunicatie la mijloc. Eu mi-am facut propria procedura, cu verificare CRC, pe care o folosesc, si o postez si aici, pentru persoane care au nevoie.

#include <OneWire.h> 

#define DS18S20_PIN 2
byte Senz1[8] = {40, 231, 99, 34, 7, 0, 0, 224};
float Temperatura = 0.0;

OneWire ds(DS18S20_PIN);

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

void loop() {	
	readTemperature(Senz1,0.0,2000UL);
}

void readTemperature(byte *_addr, float adjust, unsigned long readInterval){
static boolean flagRdTemp = 0;
static uint32_t  cMs = 0;
static uint32_t  lstreadingTemp = 0;
cMs = millis();

if ((cMs-lstreadingTemp)>readInterval) {
  if (flagRdTemp == 0) {
        Serial.print("Reading................");
	byte addr[8];  
	for (int i = 0; i < 9; i++) {
		addr[i] = _addr[i];
	}  
    
	ds.reset();
	ds.select(addr);
	ds.write(68);
	flagRdTemp = 1;
  }
  
  if ((flagRdTemp == 1) && ((cMs-lstreadingTemp)>readInterval+1000UL)){
  lstreadingTemp = cMs;  
  byte data[12];
  byte addr[8];  
	for (int i = 0; i < 9; i++) {
		addr[i] = _addr[i];
	}    
  ds.reset();
  ds.select(addr);    
  ds.write(190); // Read
  
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  
  boolean flagNoSensor = 0;
  if (data[0]+data[1] == 0)  flagNoSensor = 1;
  if (flagNoSensor) Serial.println("ERROR: No sensor or bad address");
   
  if (( OneWire::crc8( data, 8) == data[8]) && (flagNoSensor==0)) {
	byte MSB = data[1];
	byte LSB = data[0];

	float tempRead = ((MSB << 8) | LSB); 
	float TemperatureSum = (tempRead / 16)+adjust;        
	Temperatura = TemperatureSum;
        Serial.print("OK: TEMP = ");
		Serial.println(Temperatura);
  } 
  flagRdTemp = 0;
  }
 }//end.mainTimer
}

Editat de Vizitator
Link spre comentariu
  • Răspunsuri 11
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • nico_2010

    2

  • deejay2k1

    1

  • costi002

    1

  • sebip

    1

Top autori în acest subiect

e mai compacta notatia hex, iar atunci cand utilizezi bitii te ajuta sa 'vezi' locatia lor mai intuitiv (pentru unii :) )

 

exemplu: PORTD & 32 mi-mi spune mare lucru, in schimb PORTD & 0x20 imi spune ca ma uit la al 6-lea bit

Link spre comentariu

Se utilizeaza "HEX" (hexazecimal) fiindca e forma "scurta" a unui numar binar, ori microprocesoarele

folosesc numere binare (nu in format zecimal). Practic se impart cei 8 biti in doua si se "traduce" fiecare jumatate

in numarul hexazecimal corespunzator (de aceea am scris ca e forma "scurta"). Prin urmare se utilizeaza

exact numerele utilizate de catre procesor si nu echivalentele lor in zecimal.

Concret: la a doua adresa a senzorului microcontrolerul va transmite 00011111 in binar sau echivalentul 1F in hexazecimal

si doar prin convertire in zecimal va fi 231, ori primele doua forme sunt exact numerele (bitii) utilizate de catre microprocesor.

Banuiesc ca se prefera (dar nu e obligatoriul ...dupa cum se vede si din al doilea exemplu al dvs) sa se utilizeze numere hexazecimale

(sau in binar cand e important sa se urmareasca "evolutia" unui bit) pentru a putea urmari mai usor (sau mai corect) numerele "din" microprocesor.

Stiind ca trebuie sa receptionez 11111111 (binar) imi va fi mai usor sa fac o comparatie in program cu 11111111 (binar) sau FF (hexa) fata de 255 (zecimal).

Sau o alta varianta ...stiind ca numarul e pe 8 biti respectiv 2 cifre hexa risc sa fac o confuzie comparand cu numarul echivalent pe 3 cifre in zecimal datorita

numarului de cifre diferit (ca si "digiti"), chiar daca prin conversie e practic acelasi numar.

 

Parerea mea ! :-)

Editat de sebip
Link spre comentariu

pentru ca oricum nu scriem codul tot in HEX sau BINAR, ...ASM, cel putin eu nu pot si nici nu vreau, nu mai vad sensul sa notam in HEX anumite cifre. dupa mine e doar chestie de vai ce bine-arata HEX.

 

in arduino cel putin, nu scriem de ex: PORTB |= _BV(PB1); nici binar, ci doar digitalWrite(9,HIGH);

destul de departe. ma rog, pareri si pareri. ideea este ca oricum va fi compilat codul....

 

si daca e spre comfortul uman ...ma duc sa cumpar benzina ca azi e doar 0x40A70A3D RON, pe langa 45.856869, 22.950541

Editat de Vizitator
Link spre comentariu

nu e nici o fandosire în folosirea hex, este singura metodă de a lucra cu datele binare într-o formă mai compactă ce permite transformarea din hex în bin doar din ochi. De exemplu 32h îl reprezenți imediat în binar, pe cînd echivalentul în zecimal, adică 50, o să deschizi sigur calculatoru din windows ca să îl poți transforma. În plus de asta în programare chiar se lucrează cu nibble, sunt și instrucțiuni speciale pentru asta și ucm un byte are 2 nibble care în hexa sunt doar 2 caractere, e mult mai facil, plus că deși e un scris inteligibil este și foarte compact, puține caractere, de aceea este așa de folosit. Cît despre arduino nu este etalonul în programare.

Link spre comentariu

e mai usor cu hex mai ales in asamblare. Un octet poate lua valori de la 0 la 255, adica de la 1 la 3 digiti. Notatia in hexa pentru un octet va ocupa intotdeauna 2 digiti, adica de la 00h la FFh si din cauza asta tabelele hexa sunt mai usor de vazut.

In plus din hexa valoarea se transforma mult mai usor in biti. De pilda 32 zecimal inseamna 20h = 0010_0000

Tot in hexa transformarile din caractere mici se fac mult mai usor decat in zecimal:

De pilda "A" e 65 zecimal sau 41h iar "a" este 97 zecimal sau 61h. Pentru a transforma "A" in "a" e simplu:

mov a,41h adica 0100_0001 sau in zecimal: mov a,65

or a,20h adica 0010_0000 or a,32

in a vom avea:

a=61h adica 0110_0001 sau a=97 in zecimal

in zecimal e foarte greoi sa vezi vreo legatura intre 65 si 97 dar in hexa vezi imediat ca intre 41h si 61h difera doar bitul 5 si ca primul e caracter majuscula.

la fel si la numere:

caracterul "1" este 49 zecimal, 31h sau 0011_0001 binar

caracterul "2" este 50 zecimal, 32h sau 0011_0010 binar

caracterul "9" este 57 zecimal, 39h sau 0011_1001 binar

Dupa cum vezi in hexa sau binar este mult mai usor decat in zecimal

Este suficient sa faci AND R,0b_0000_1111 sau AND R,0x0F pentru a transforma un numar ASCII intr-un numar binar cu care poti face calcule.

Tot la fel de usor poti transforma un numar intre 00h si 09h dintr-un registru pentru a-l converti in ASCII si a-l putea afisa. Folosesti doar OR R,0x30

 

Senzorii digitali sau convertoarele AD dau datele la iesire digital. Daca folosesti datele pentru calcule exact asa cum le da senzorul sau convertorul AD si faci cu ele calcule doar in format hexa (binar), viteza de lucru e foarte mare. In schimbi daca le transformi zecimal si pe urma le folosesti la calcule, viteza scade foarte mult. Datele trebuiesc transformate din hexa in zecimal doar atunci cand sunt afisate pe un display pentru a nu pierde din viteza. Mai ales atunci cand microcontrolerele sunt folosite pentru surse stabilizate PWM, iar stabilizarea se face cu ajutorul convertorului AD intern.

Si atunci cand folosesti afisaje, si ai de calculat o pozitie de afisat, e mult mai simplu atunci cand folosesti hexa. Mai ales la afisajele grafice.

Editat de cimitavita
Link spre comentariu

...

 

Senzorii digitali sau convertoarele AD dau datele la iesire digital. Daca folosesti datele pentru calcule exact asa cum le da senzorul sau convertorul AD si faci cu ele calcule doar in format hexa (binar), viteza de lucru e foarte mare...

Salut! Este interesant ce ai zis aici, poti sa dai un exemplu te rog?

Link spre comentariu

Asta cu viteza mai mica sau mai mare daca scrii constantele in codul sursa nu e adevarat, compilatorul in sine optimizeaza si genereaza exact acelasi rezultat. Tot ce difera e "omul" ce scrie respectivul cod si ce stil prefera.

Link spre comentariu

OK! Si care este morala? Raspunsul la intrebare l-ai fi putut afla cautand pe goagle. Nu mai accept subiecte fara legatura (sau cu legatura fortata) cu Arduino.Voi muta subiectul la sectiunea pentru incepatori acolo ii este locul.

Link spre comentariu

raspunsul la orice intrebare il gasim pe Google. Dar google nu interactioneaza, si nu e acel spirit de forum. Ma trimiti pe google....cu un topic de forum evident ?

 

ceea ce am scris eu are exact si direct legatura cu Arduino. daca raspunsurile au luat-o prin asm sau alte chestii ce vina are Topicul ? Eu ma refeream strict la mediul Arduino IDE, de-asta si postasem colo, dar in fine.

 

Am inteles ideea, orice postez eu nu are legatura cu Arduino. O sa postam pe Google...ce sa mai...


Mai tine , cred, si de datasheet. Comenzile , in cazul lui ds18b20, sunt date in hexa direct. Ar avea rost sa stai sa le convertești in zecimal cand scrii codul?

Aici ai dreptate.

Editat de Vizitator
Link spre comentariu

Raspunsul la intrebarea ta este: tine de comoditate si nu conteaza daca scrii niste valori in hexazecimal, in zecimal, in octal sau in binar. Acele valori vor avea aceeasi reprezentare la compilare.

Asa ca intrebarea ta nu isi avea rostul.

Te-ai obisnuit sa postezi solicitari cu caracter general la sectiunea Arduino si asta este motivul pentru care le-am mutat si le voi mai muta.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări