This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I am getting -1 on the screen when I save an unint32 and read it back? I am using BLEnano

uint32_t value = 99999;

lcd.clear(); lcd.setPosition(0,1); lcd.printf("Writing bytes 0-16\n");

i2c.start();

data[0] = 0; data[1] = 0;
data[2] = ((value >> 24) & 0xFF); i2c.write(0xA0, data, 3); wait (0.1);

data[0] = 0; data[1] = 1;
data[2] = ((value >> 16) & 0xFF); i2c.write(0xA0, data, 3); wait (0.1);

data[0] = 0; data[1] = 2;
data[2] = ((value >> 8) & 0xFF); i2c.write(0xA0, data, 3); wait (0.1);

data[0] = 0; data[1] = 3;
data[2] = (value & 0xFF); i2c.write(0xA0, data, 3); wait (0.1);

//READ //Setting read pointer to 0 value = 0; data[0] = 0; // MSB address data[1] = 0; // LSB address

i2c.write(0xA0, data, 2);

char response[4]; i2c.read(0xA0+0x01, response, 4); value = ((response[0]<<24) | (response[1]<<16) | (response[2]<<8) | response[3]);

lcd.clear(); lcd.setPosition(0,0); lcd.printf("%d", value); wait(5);

Parents
  • For the first thing, have you tried reading the response array and check what the bytes contain? I'm guessing they're all 255.

    Also, this part doesn't do what the comment says:

    //READ //Setting read pointer to 0 value = 0; data[0] = 0; // MSB address data[1] = 0; // LSB address
    
    i2c.write(0xA0, data, 2);
    

    I have no idea what device you're communicating with, but when you call i2c.write(0xA0, data, 2), your array is still data[0] = 0, data[1] = 3 and data[2] = 159 from the previous command.


    Edit 2017-04-28:

    Are you sure your i2c.read() function requires you to add the read bit to the address (0xA0+1)? I don't know what I2C driver you're using, but I'd think the function would be implemented in such a manner that you'd just pass the device address (0xA0) and it automatically adds the read bit.

    Try this (untested):

    uint32_t value = 99999;
    
    lcd.clear(); 
    lcd.setPosition(0,1); 
    lcd.printf("Writing bytes 0-16\n");
    
    data[0] = 0; 
    data[1] = 0;
    data[2] = ((value >> 24) & 0xFF); 
    int err_code = i2c.write(0xA0, data, 3);
    wait(0.1);
    if(err_code != 0) {
    	lcd.clear(); 
    	lcd.setPosition(0,0); 
    	lcd.printf("I2C write error: %d", err_code);
    	wait(5);
    }
    
    data[0] = 0; 
    data[1] = 1; 
    data[2] = ((value >> 16) & 0xFF); 
    i2c.write(0xA0, data, 3); 
    wait(0.1);
    
    data[0] = 0; 
    data[1] = 2; 
    data[2] = ((value >> 8) & 0xFF); 
    i2c.write(0xA0, data, 3); 
    wait(0.1);
    
    data[0] = 0; 
    data[1] = 3; 
    data[2] = (value & 0xFF); 
    i2c.write(0xA0, data, 3); 
    wait(0.1);
    
    // Read from address 0
    data[0] = 0; // MSB address 
    data[1] = 0; // LSB address
    i2c.write(0xA0, data, 2);
    
    char response[4]; 
    i2c.read(0xA0, response, 4);
    value = (response[0]<<24) | (response[1]<<16) | (response[2]<<8) | response[3];
    
    lcd.clear(); 
    lcd.setPosition(0,0); 
    lcd.printf("%d", value); 
    wait(5);
    

    And please try to refrain from multiple statements per line. It makes the code very hard to read.

  • #include "SoftI2C.h"

    SoftI2C::SoftI2C(PinName sda, PinName scl) : _sda(sda), _scl(scl) { // Set defaults _sda.mode(PullNone); _scl.mode(PullNone); _sda.input(); _scl.input(); frequency(100000);

    active = false;
    
    }
    

    void SoftI2C::frequency(int hz) { delay_us = 1000000 / hz / 4; //delay is a quarter of the total period }

    int SoftI2C::read(int address, char *data, int length, bool repeated) { start();

    // Write address with LSB to one
    if (write(address | 0x01) == 0) {
        return 1;
    }  
    
    // Read the data
    for(int i = 0; i<length - 1; i++) {
        data[i] = read(1);
    }
    data[length-1] = read(0);
    
    if (repeated == false) {
        stop();
    }
    return 0;
    

    }

    int SoftI2C::write(int address, const char *data, int length, bool repeated) { start();

    // Write address with LSB to zero
    if (write(address & 0xFE) == 0) {
        return 1;
    }  
    
    // Write the data
    for(int i = 0; i<length; i++) {
        if(write(data[i]) == 0) {
            return 1;
        }
    }
    
    if (repeated == false) {
        stop();
    }
    return 0;
    

    }

    int SoftI2C::read(int ack) { int retval = 0; _scl.output();

    // Shift the bits out, msb first
    for (int i = 7; i>=0; i--) {
        //SCL low
        _scl.write(0);
        _sda.input();
        wait_us(delay_us);
        
        //read SDA
        retval |= _sda.read() << i;
        wait_us(delay_us);
        
        //SCL high again
        _scl.write(1);
        wait_us(delay_us << 1); //wait two delays
    }
    
    // Last cycle to set the ACK
    _scl.write(0);
    if ( ack ) {
        _sda.output();
        _sda.write(0);
    } else {
        _sda.input();
    }
    wait_us(delay_us << 1);
    
    _scl.write(1);
    wait_us(delay_us << 1);
    
    
    return retval;
    

    }

    int SoftI2C::write(int data) { _scl.output();

    // Shift the bits out, msb first
    for (int i = 7; i>=0; i--) {
        //SCL low
        _scl.write(0);
        wait_us(delay_us);
        
        //Change SDA depending on the bit
        if ( (data >> i) & 0x01 ) {
            _sda.input();
        } else {
            _sda.output();
            _sda.write(0);
        }
        wait_us(delay_us);
        
        //SCL high again
        _scl.write(1);
        wait_us(delay_us << 1); //wait two delays
    }
    
    // Last cycle to get the ACK
    _scl.write(0);
    wait_us(delay_us);
    
    _sda.input();
    wait_us(delay_us);
    
    _scl.write(1);
    wait_us(delay_us);
    int retval = ~_sda.read(); //Read the ack
    wait_us(delay_us);
    
    return retval;
    

    }

    void SoftI2C::start(void) { if (active) { //if repeated start //Set SDA high, toggle scl _sda.input(); _scl.output(); _scl.write(0); wait_us(delay_us << 1); _scl.write(1); wait_us(delay_us << 1); } // Pull SDA low _sda.output(); _sda.write(0); wait_us(delay_us); active = true; }

    void SoftI2C::stop(void) { // Float SDA high _scl.output(); _scl.write(0); _sda.output(); _sda.write(0); wait_us(delay_us); _scl.input(); wait_us(delay_us); _sda.input(); wait_us(delay_us);

    active = false;
    

    }

Reply
  • #include "SoftI2C.h"

    SoftI2C::SoftI2C(PinName sda, PinName scl) : _sda(sda), _scl(scl) { // Set defaults _sda.mode(PullNone); _scl.mode(PullNone); _sda.input(); _scl.input(); frequency(100000);

    active = false;
    
    }
    

    void SoftI2C::frequency(int hz) { delay_us = 1000000 / hz / 4; //delay is a quarter of the total period }

    int SoftI2C::read(int address, char *data, int length, bool repeated) { start();

    // Write address with LSB to one
    if (write(address | 0x01) == 0) {
        return 1;
    }  
    
    // Read the data
    for(int i = 0; i<length - 1; i++) {
        data[i] = read(1);
    }
    data[length-1] = read(0);
    
    if (repeated == false) {
        stop();
    }
    return 0;
    

    }

    int SoftI2C::write(int address, const char *data, int length, bool repeated) { start();

    // Write address with LSB to zero
    if (write(address & 0xFE) == 0) {
        return 1;
    }  
    
    // Write the data
    for(int i = 0; i<length; i++) {
        if(write(data[i]) == 0) {
            return 1;
        }
    }
    
    if (repeated == false) {
        stop();
    }
    return 0;
    

    }

    int SoftI2C::read(int ack) { int retval = 0; _scl.output();

    // Shift the bits out, msb first
    for (int i = 7; i>=0; i--) {
        //SCL low
        _scl.write(0);
        _sda.input();
        wait_us(delay_us);
        
        //read SDA
        retval |= _sda.read() << i;
        wait_us(delay_us);
        
        //SCL high again
        _scl.write(1);
        wait_us(delay_us << 1); //wait two delays
    }
    
    // Last cycle to set the ACK
    _scl.write(0);
    if ( ack ) {
        _sda.output();
        _sda.write(0);
    } else {
        _sda.input();
    }
    wait_us(delay_us << 1);
    
    _scl.write(1);
    wait_us(delay_us << 1);
    
    
    return retval;
    

    }

    int SoftI2C::write(int data) { _scl.output();

    // Shift the bits out, msb first
    for (int i = 7; i>=0; i--) {
        //SCL low
        _scl.write(0);
        wait_us(delay_us);
        
        //Change SDA depending on the bit
        if ( (data >> i) & 0x01 ) {
            _sda.input();
        } else {
            _sda.output();
            _sda.write(0);
        }
        wait_us(delay_us);
        
        //SCL high again
        _scl.write(1);
        wait_us(delay_us << 1); //wait two delays
    }
    
    // Last cycle to get the ACK
    _scl.write(0);
    wait_us(delay_us);
    
    _sda.input();
    wait_us(delay_us);
    
    _scl.write(1);
    wait_us(delay_us);
    int retval = ~_sda.read(); //Read the ack
    wait_us(delay_us);
    
    return retval;
    

    }

    void SoftI2C::start(void) { if (active) { //if repeated start //Set SDA high, toggle scl _sda.input(); _scl.output(); _scl.write(0); wait_us(delay_us << 1); _scl.write(1); wait_us(delay_us << 1); } // Pull SDA low _sda.output(); _sda.write(0); wait_us(delay_us); active = true; }

    void SoftI2C::stop(void) { // Float SDA high _scl.output(); _scl.write(0); _sda.output(); _sda.write(0); wait_us(delay_us); _scl.input(); wait_us(delay_us); _sda.input(); wait_us(delay_us);

    active = false;
    

    }

Children
No Data
Related