Sari la conținut
ELFORUM - Forumul electronistilor

Nixie termometru si higrometru cu PIC16F876 si SHT21


Postări Recomandate

Nu. Ca sa stingi un digit trebuie sa scrii o valoare de 4 biti care sa fie mai mare ca 9. Vezi tabela de adevar din datasheet-u lui 74141. de ex daca scrii A=B=C=D= H (5v) teoretic nu trebuie sa ai nici un digit aprins. 1111 in binar = 15 in dec

Daca faci portul intrare ( TRISport=1) atunci intrarile lui 74141 vor ramane in "aer" si nu se stie ce va afisa.... cel mai probabil 0

Editat de djvas
Link spre comentariu
  • Răspunsuri 25
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

Da, din tabela de adevar a lui 74141 pt. intrare in BCD > 9 iesirile nu sunt active (NONE). Am facut simularea cu digiti 7 Seg. BCD si la intrare 1111 imi afisa F, m-a dus in eroare chestia asta, nu am mai lucrat cu Nixie si nu stiu exact cum se comporta, dar cred ca ai dreptate, daca nici o iesire nu este activa atunci Nixie nu va aprinde nici o cifra.

Link spre comentariu
  • 2 săptămâni mai târziu...

Salut, incerc sa folosesc I2C pt. a comunica cu senzorul SHT21 dar nu prea-mi iese...

Simuland in Proteus si folosind I2C Debugger, atat cat ma pricep eu sa interpretez datele, se pare ca nu reusesc sa citesc datele din senzor. 

Atasat: schema in proteus, hex-ul si datasheet SHT21. 

Cam asta ar fi bucata de cod:

#define sht21     0b10000000#define softreset 0b11111110#define temphold  0b11100011#define humidhold 0b11100101#define read      0b10000001int calc, temp;int msbtemp, lsbtemp;void SoftResett() {   I2C1_Start();                                   // issue I2C start signal   I2C1_Wr(sht21);   I2C1_Wr(softreset);   I2C1_Stop();   Delay_ms(15); } void HTU21D_REG_write(){  I2C1_Start();  I2C1_Wr(sht21);  I2C1_Wr(temphold);  I2C1_Stop(); } void HTU21D_REG_read() {  I2C1_Start();  I2C1_Wr(read);  msbtemp = I2C1_Rd (1u);  lsbtemp = I2C1_Rd (0u);  I2C1_Stop();} unsigned HTU21D_ReadValue() {   lsbtemp &= ~0x03;                         //last 2 bits of LSB set to 0   msbtemp = msbtemp << 8;   temp =(msbtemp | lsbtemp);   return temp; } void procTemperatureValue(temp) {  calc = -46 + 175 * temp / 65536.0;         // T=46.85+175.72* temp/65536 }void main() {     //OPTION_REG     //INTCON.GIE = 1;     ADCON1 = 0B00000111;     TRISA = 0;     TRISB = 0;     TRISC = 0;     PORTA = 0;     PORTB = 0;     PORTC = 0;     T1CON = 0b00000101;    // INTCON.PEIE = 0x01;    // Bit6 Enable Peripheral interrupts    // PIE1.TMR1IE = 0x01;    // Timer1 interrupt enabled    // PIR1.TMR1IF = 0x00;    // Timer1 interrupt Flag cleared    // TMR1L = 0x00;          // Reset Timer1 lower 8 bits    // TMR1H = 0x00;          // Reset Timer1 upper 8 bits   while (1)   {    I2C1_Init(10000);    SoftResett();    HTU21D_REG_write();    HTU21D_REG_read();   }  }

Sensirion_Humidity_Sensors_SHT21_Datasheet_V4.pdf

1t.rar

New Nixie SHT21 26 martie.hex.txt

Link spre comentariu

Am incercat alt software dupa modelul de la Sensirion dar tot nu reusesc sa citesc sensorul. Are cineva vreo idee, ce-i gresit aici?

//SHT21 connectionssbit SDA at RC4_bit;                     // Serial data pinsbit SCL at RC3_bit;                     // Serial clock pinsbit SDA_Direction at TRISC4_bit;        // Serial data direction pinsbit SCL_Direction at TRISC3_bit;        // Serial clock direction pinchar error = 0;                          //variable for error codefloat humidityRH;                        //variable for relative humidity[%RH] as floatfloat temperatureC;                      //variable for temperature[°C] as float// I2C leveltypedef enum {LOW = 0, HIGH = 1}etI2cLevel;// I2C acknowledgetypedef enum {ACK = 0, NO_ACK = 1}etI2cAck;// Error codestypedef enum {ACK_ERROR = 0x01, TIME_OUT_ERROR = 0x02, CHECKSUM_ERROR = 0x04,UNIT_ERROR = 0x08}etError;// sensor commandtypedef enum { TRIG_T_MEASUREMENT_HM = 0b11100011,      // command trig. temp meas. hold master TRIG_RH_MEASUREMENT_HM = 0b11100101,     // command trig. humidity meas. hold master SOFT_RESET = 0b11111110                  // command soft reset }etSHT2xCommand;// measurement signal selectiontypedef enum {HUMIDITY, TEMP}etSHT2xMeasureType;typedef enum { I2C_ADR_W = 0b10000000,                    // sensor I2C address + write bit I2C_ADR_R = 0b10000001                     // sensor I2C address + read bit }etI2cHeader;typedef union{  unsigned int u16;                         // element specifier for accessing whole u16  signed int i16;                           // element specifier for accessing whole i16  struct {  #ifdef LITTLE_ENDIAN                      // Byte-order is little endian  unsigned char u8L;                        // element specifier for accessing low u8  unsigned char u8H;                        // element specifier for accessing high u8  #else                                     // Byte-order is big endian  unsigned char u8H;                        // element specifier for accessing low u8  unsigned char u8L;                        // element specifier for accessing high u8  #endif } s16;                                     // element spec. for acc. struct with low or high u8} nt16;nt16 sRH;                                   //variable for raw humidity ticksnt16 sT;                                    //variable for raw temperature tickstypedef union{ unsigned long u32;                         // element specifier for accessing whole u32 signed long i32;                           // element specifier for accessing whole i32 struct {  #ifdef LITTLE_ENDIAN                      // Byte-order is little endian  unsigned int u16L;                        // element specifier for accessing low u16  unsigned int u16H;                        // element specifier for accessing high u16  #else                                     // Byte-order is big endian  unsigned int u16H;                        // element specifier for accessing low u16  unsigned int u16L;                        // element specifier for accessing high u16  #endif } s32;                                     // element spec. for acc. struct with low or high u16} nt32;void I2c_Init (void)                        //Initializes the ports for I2C interface {  SDA_Direction = LOW;                      // Set port as output for configuration  SCL_Direction = LOW;                      // Set port as output for configuration  SDA = LOW;                                // Set SDA level as low for output mode  SCL = LOW;                                // Set SCL level as low for output mode  SDA_Direction = HIGH;                     // I2C-bus idle mode SDA released (input)  SCL_Direction = HIGH;                     // I2C-bus idle mode SCL released (input) } void I2c_StartCondition (void)             // writes a start condition on I2C-bus {  SDA_Direction = HIGH;  SCL_Direction = HIGH;  SDA_Direction = LOW;  Delay_us(10);                              // hold time start condition (t_HD;STA)  SCL_Direction = LOW;  Delay_us(10); }void I2c_StopCondition (void)                // writes a stop condition on I2C-bus {  SDA_Direction = LOW;  SCL_Direction = LOW;  SCL_Direction = HIGH;  Delay_us(10);                              // set-up time stop condition (t_SU;STO)  SDA_Direction = HIGH;  Delay_us(10); }unsigned char SHT2x_CheckCrc(unsigned char dat[], unsigned char nbrOfBytes, unsigned char checksum) {   unsigned char crc=0;   unsigned char byteCtr;   unsigned char k;                                       //counting variable   //calculates 8-Bit checksum with given polynomial   for (byteCtr = 0; byteCtr<nbrOfBytes; ++byteCtr)   {     crc ^= (dat[byteCtr]);                          //crc ^ (dat[byteCtr]);     for (k = 8; k > 0; --k)     {      if (crc & 0x80) crc = ((crc << 1) ^ 0x0131);      else crc = (crc << 1);     }   }   if (crc != checksum) return CHECKSUM_ERROR;   else   return 0; }unsigned char I2c_WriteByte (unsigned char txByte)        // writes a byte to I2C-bus and checks acknowledge {  unsigned char mask, error=0;  for (mask=0x80; mask>0; mask>>=1)                       //shift bit for masking (8 times)  {    if ((mask & txByte) == 0)     SDA_Direction = LOW;                                  //masking txByte, write bit to SDA-Line    else     SDA_Direction = HIGH;    Delay_us(1);                                          //data set-up time (t_SU;DAT)    SCL_Direction = HIGH;                                 //generate clock pulse on SCL    Delay_us(5);                                          //SCL high time (t_HIGH)    SCL_Direction = LOW;    Delay_us(1);                                          //data hold time(t_HD;DAT)  }  SDA_Direction = HIGH;                                   //release SDA-line  SCL_Direction = HIGH;                                   //clk #9 for ack  Delay_us(1);                                            //data set-up time (t_SU;DAT)  if(SDA == HIGH)  error = ACK_ERROR;                                      //check ack from i2c slave  SCL_Direction = LOW;  Delay_us(20);                                           //wait time to see byte package on scope  return error;                                           //return error code }unsigned char I2c_ReadByte(etI2cAck ack)                  // reads a byte on I2C-bus {  unsigned char mask, rxByte=0;  SDA_Direction = HIGH;                                   //release SDA-line  for (mask=0x80; mask>0; mask>>=1)                       //shift bit for masking (8 times)  {    SCL_Direction = HIGH;                                 //start clock on SCL-line    Delay_us(1);                                          //data set-up time (t_SU;DAT)    Delay_us(3);                                          //SCL high time (t_HIGH)    if (SDA == HIGH)    rxByte=(rxByte | mask);                               //read bit    SCL_Direction = LOW;    Delay_us(1);                                          //data hold time(t_HD;DAT)  }    SDA_Direction = ack;                                  //send acknowledge if necessary    Delay_us(1);                                          //data set-up time (t_SU;DAT)    SCL_Direction = HIGH;                                 //clk #9 for ack    Delay_us(5);                                          //SCL high time (t_HIGH)    SCL_Direction = LOW;    SDA_Direction = HIGH;                                 //release SDA-line    _Direction    Delay_us(20);                                         //wait time to see byte package on scope    return rxByte;                                        //return error code }unsigned char SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType, nt16 *pMeasurand) {  unsigned char checksum;                            //checksum  unsigned dat[2];                                   //data array for checksum verification;  unsigned char error=0;                             //error variable  unsigned int i;                                    //counting variable //-- write I2C sensor address and command --  I2c_StartCondition();  error |= I2c_WriteByte(I2C_ADR_W);                  // I2C Adr  switch(eSHT2xMeasureType)  {   case HUMIDITY: error |= I2c_WriteByte (TRIG_RH_MEASUREMENT_HM); break;   case TEMP :    error |= I2c_WriteByte (TRIG_T_MEASUREMENT_HM); break;   default: error = 0;  }  //-- wait until hold master is released --  I2c_StartCondition();  error |= I2c_WriteByte (I2C_ADR_R);  SCL_Direction = HIGH;                       // set SCL I/O port as input  for(i=0; i<1000; i++)                       // wait until master hold is released or  {   Delay_us(1000);                            // a timeout (~1s) is reached   if (SCL == 1) break;  }  //-- check for timeout --  if(SCL == 0)  error |= TIME_OUT_ERROR;  //-- read two data bytes and one checksum byte --  pMeasurand->s16.u8H = dat[0] = I2c_ReadByte(ACK);  pMeasurand->s16.u8L = dat[1] = I2c_ReadByte(ACK);  checksum=I2c_ReadByte(NO_ACK);  // --verify checksum --  error |= SHT2x_CheckCrc (dat,2,checksum);  I2c_StopCondition();  return error; }unsigned char SHT2x_SoftReset()                          // performs a reset{ unsigned char error=0;                                  //error variable I2c_StartCondition(); error |= I2c_WriteByte (I2C_ADR_W);                     // I2C Adr error |= I2c_WriteByte (SOFT_RESET);                    // Command I2c_StopCondition(); Delay_us(15000);                                        // wait till sensor has restarted return error;}float SHT2x_CalcRH(int u16sRH)                             // calculates the relative humidity {  float humidityRH;                                        // clear bits [1..0] (status bits)  u16sRH &= ~0x0003;                                       // variable for result  //-- calculate relative humidity [%RH] --  humidityRH = -6.0 + 125.0*(float)u16sRH/65536;                  // RH= -6 + 125 * SRH/2^16  return humidityRH; }float SHT2x_CalcTemperatureC(int u16sT)                    // calculates temperature {  float temperatureC;                                      // variable for result  u16sT &= ~0x0003;                                        // clear bits [1..0] (status bits)  //-- calculate temperature [°C] --  temperatureC = -46.85 + 175.72*(float)u16sT/65536 ;      //T= -46.85 + 175.72 * ST/2^16  return temperatureC; }void main() {     //OPTION_REG = 0b00001001;     //INTCON.GIE = 1;     ADCON1 = 0b00000111;     TRISA = 0;     TRISB = 0;     TRISC = 0;     PORTA = 0;     PORTB = 0;     PORTC = 0;     T1CON = 0b00000101;     // INTCON.PEIE = 0x01;    // Bit6 Enable Peripheral interrupts     // PIE1.TMR1IE = 0x01;    // Timer1 interrupt enabled     // PIR1.TMR1IF = 0x00;    // Timer1 interrupt Flag cleared     //TMR1L = 0x00;          // Reset Timer1 lower 8 bits     //TMR1H = 0x00;          // Reset Timer1 upper 8 bits     //INTCON.GIE  = 0x01;    // Bit7 enable Global interrupts    I2c_Init (void);    Delay_ms(20);                                            //wait for sensor initialization t_powerUp (15ms) while (1) {   error = 0;                                                // reset error status   // --- Reset sensor by command ---   error |= SHT2x_SoftReset();   // --- measure humidity with "Hold Master Mode (HM)"  ---   error |= SHT2x_MeasureHM(HUMIDITY, &sRH);   //-- calculate humidity and temperature --   //temperatureC = SHT2x_CalcTemperatureC(sT.u16);   humidityRH   = SHT2x_CalcRH(sRH.u16); }}
Link spre comentariu
  • 2 săptămâni mai târziu...

Nu am verificat codurile de mai sus... dar am avut si eu o experienta neplacuta cu Proteus si I2C in trecut. Era un cod foarte simplu (o comunicatie I2C intre un pic si un dac) care nu a mers simulat. L-am  scris in PIC si a functionat din prima fara probleme.

Link spre comentariu

Am facut doua programe, cel de la #18 in care folosesc librariile MikroC pentu I2c si cel de la #19 in care incerc sa comand direct SDA si SCL.

Am facut un program similar pt. senzorul SHT11 si acesta functioneaza, dar protocolul de comunicare intre senzor si PIC este diferit diferit fata de SHT 21.

Nu ma pricep sa fac debugging la software, din cate am vazut si cat ma pricep se pare ca nu mai iese dintr-o bucla sau asa ceva.

Cu I2C debugger din Proteus am vazut ca face reset la senzor, scrie adresa si comanda dar nu citeste datele din senzor. Cel putin asa cred....

Link spre comentariu
  • 1 lună mai târziu...

incearca un singur ciclu de citire (muta corpul din while(1) inainte de while, si lasa while-ul fara cod) apoi pune stare de eroare pe niste pini liberi sau leduri de test, ce ai la indemana (RA0-RA3 par liberi).

testeaza eroare in felul urmator: (pinii analogici e posibil sa trebuiasca setati pentru iesire digitala, daca ii folosesti in forma data de mine)

if ( error & ACK_ERROR )  RA0 = 1;if ( error & TIME_OUT_ERROR )  RA1 = 1;if ( error & CHECKSUM_ERROR )  RA2 = 1;if ( error & UNIT_ERROR )  RA3 = 1;if ( 0 == error )  RA0 = RA1 = RA2 = RA3 = 0;
Link spre comentariu

conectarea senzorului mi se pare cam la limita dpdv electric. Chip-ul merge intre 2V si 3.6V, fiind de 3V ca nivel high uzual. Alimetarea sa se face prin doua diode de la 5V, ceea ce il duce in maxim din prima la 3.6V, daca nu si peste putin. Liniile de date nu sunt complet izolate de 5V dat de MCU, cand are pin de iesire pe high. Anumite integrate de 3.3V sunt compatibile pe pinii de comunicatie cu nivele de 5V, dar nu vad sa specifice acest lucru si pentru chipul asta.

eu as fi folosit un adaptor de nivele, ceva in genu asta: https://www.sparkfun.com/products/12009

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