Jump to content

Bug em código para ler string EEPROM


PsySc0rpi0n
Go to solution Solved by PsySc0rpi0n,

Recommended Posts

Boas.

Estou a escrever um pequeno código para escrever e ler uma string (ou várias) numa eeprom, usando o protocolo I2C e livrarias do Arduino.

O sistema é composto pelo seguinte:

USB-TTL <-> ESP8266 <-> EEPROM

O código completo pode ser consultado aqui.

 

O que acontece é que a livraria Wire.h para o ESP8266 tem um buffer the 128 bytes e portanto, se a string tiver mais que 128 bytes, eu tenho que fazer a leitura por várias vezes.

Ao fazer a leitura de 128 bytes em 128 bytes, o que me está a acontecer é que no 128º byte, eu recebo um NACK do I2C e embora na próxima leitura de 128 bytes eu esteja a ler este último byte que devolveu NACK e de a string estar completa, não consigo perceber porque é que neste byte 128 recebo sempre um NACK em vez de um ACK.

A função que lê os bytes e os envia para a porta série é a seguinte:

// Read bytes from eeprom device
void readEEPROM(uint8_t intaddr, uint16_t datalen){
    char singleChar;
    for(uint16_t i = 0; i < datalen; i++){
        if(!(i % 128)){
            Wire.beginTransmission(I2C_SLAVE_ADDR7);
            Wire.write(intaddr + i);
            Wire.endTransmission();
            Wire.requestFrom(I2C_SLAVE_ADDR7, (int) (datalen - i));
        }
        singleChar = Wire.read();
        Serial.print(singleChar);
    }
}

Se alguém me conseguir identificar o bug, ou se me souber explicar porque é que isto acontece ou se é normal acontecer, eu agradeço.

 

Edited;

É isto que acontece:

0d53805a4821e05d1a80dbf60ec8de73730c7b2c

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

  • Solution
On 6/2/2023 at 4:27 PM, sergio17 said:

if(!(i % 128)) esta condição não executa a lógica se o i=128 ou se o i=0 que é onde estas a ter o problema. Não sei se ajuda 

Aí só pretendo verificar quando é que o i é igual a 128, através do operador % (remainder), que devolve 0 caso o i seja igual a 128.

Mas já cheguei à conclusão que afinal não há bug nenhum. Segundo as especificações do protocolo I²C, no fim de um ciclo de leitura, o último byte do ciclo devolve NACK.

Quote

If the controller wishes to read from the target, then it repeatedly receives a byte from the target, the controller sending an ACK bit after every byte except the last one.

E a função alterou um pouco:

void readBytes(uint8_t intaddr, uint16_t dataln){
    char singleChar;
    uint16_t req = 128;

    if(dataln <= 128){
        Wire.beginTransmission(I2C_SLAVE_ADDR7);
        Wire.write(intaddr);
        Wire.endTransmission();
        Wire.requestFrom(I2C_SLAVE_ADDR7, (int) (dataln));
        for(uint8_t i = 0; i < dataln; i++){
            singleChar = Wire.read();
            Serial.print(singleChar);
        }
    }else{
        for(uint8_t i = 0; i <= (dataln + i - 1) / dataln; i++){
            Wire.beginTransmission(I2C_SLAVE_ADDR7);
            Wire.write(intaddr + i * 128);
            Wire.endTransmission();
            Wire.requestFrom(I2C_SLAVE_ADDR7, (int) (req));
            for(uint8_t j = 0; j < req; j++){
                singleChar = Wire.read();
                Serial.print(singleChar);
            }
            req = dataln - 128;
        }
    }
}

 

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.