B4R Question I2C External EEPROM - rwire

Discussion in 'B4R Questions' started by rodmcm, Nov 22, 2018.

  1. rodmcm

    rodmcm Member Licensed User

    I noticed that other questioners on this either never reported success or reverted to inline C

    Enclosed is a B4r interpretation of the Arduino method for a single byte store and return to External EEPROM. I tested with I2C scan and the EEPROM does exist!

    www.hobbytronics.co.uk/arduino-external-eeprom

    Irrespective of the value or location I place the byte of data the return always is the same (3). I changed the program from reading one byte request to reading 10 and printed out and get the surprising answer
    3,4,5,6,7,8,9,10,11,12

    Has anyone successfully read to an external memory chip with B4r? Assistance required please
     

    Attached Files:

  2. Erel

    Erel Administrator Staff Member Licensed User

    Start with running the code from that link. Does it work properly?
     
  3. rodmcm

    rodmcm Member Licensed User

    yes
    I have used this method for a long time ago for arduino and ESP projects. Some commercial. I am porting them to b4r mainly due to the security of B4r serialization.

    The only difference I can see between the arduino and what I have written in B4r is the method of writing for the location. The arduino writes the MSB and the LSB as two separate messages.


    //Write to the EEPROM
    //========================================================================
    void WriteEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
    {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(data);
    Wire.endTransmission();
    delay(5);
    }

    //Read From the EEPROM
    //========================================================================
    byte ReadEEPROM(int deviceaddress, unsigned int eeaddress )
    {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
    }
     
  4. rodmcm

    rodmcm Member Licensed User

    I have just tried the single writes of MSB and LSB as well and the answers are
    81,82,83,84,85,86,87,88,89,90
     
  5. rodmcm

    rodmcm Member Licensed User

    had another go
    Wrote and verified 20 random bytes (Arduino1)
    Ran B4r and extracted 10 bytes that do no match the inserted values (B4r1)
    With Arduino printed out the first 20 bytes again (Arduino2)

    Low and behold the new bytes are not the same as those written originally
    But the 10 extracted bytes by B4r appear on the new list from location 2 down!

    My brain hurts, going to bed
     

    Attached Files:

  6. Erel

    Erel Administrator Staff Member Licensed User

    Try this:
    Code:
    Sub Process_Globals
       
    Public Serial1 As Serial
       
    Private wire As WireMaster
    End Sub

    Private Sub AppStart
       Serial1.Initialize(
    115200)
       
    Log("AppStart")
       wire.Initialize   
    End Sub

    Sub WriteEEPROM (DeviceAddress As Int, EEAddress As UInt, Value As Byte) 
       
    Dim Data(5As Byte
       
    Dim raf As RandomAccessFile
       raf.Initialize(Data, 
    True)
       raf.WriteInt16(
    Bit.ShiftRight(EEAddress, 8), raf.CurrentPosition)
       raf.WriteInt16(
    Bit.And(EEAddress, 0xff), raf.CurrentPosition)
       raf.WriteByte(Value, raf.CurrentPosition)
       wire.WriteTo(DeviceAddress, Data)
    End Sub
     
  7. rodmcm

    rodmcm Member Licensed User

    No, unfortunately..

    I filled the first 20 ext EEProm memory locations with bytes 1 to 20. Then ran my original read and this 'read' based on the methods of your 'write'

    Code:
    Sub ReadExtEEPROM (DeviceAddress As Int, EEAddress As UInt) As Byte
        
    Dim Data(5As Byte
        
    Dim raf As RandomAccessFile
        raf.Initialize(Data, 
    True)
        raf.WriteInt16(
    Bit.ShiftRight(EEAddress, 8), raf.CurrentPosition)
        raf.WriteInt16(
    Bit.And(EEAddress, 0xff), raf.CurrentPosition)
        wire.WriteTo(DeviceAddress, Data)
        Delay(
    5)
        
    Dim Answer() As Byte = wire.RequestFrom(DeviceAddress,10)      ' just for fun
        Log("Answer Length  ",Answer.Length)
        
    If Answer.Length>0 Then
            
    For i=0 To Answer.Length-1
                
    Log(Answer(i))
            
    Next
            
    Return Answer(0)
        
    End If
    End Sub
    in both cases when I then read the 20 positions with Arduino
    0 = EEadress (tested by changing EEaddress a few times)
    1=0
    2=0
    3=4
    4=5 etc

    The 10 read locations were always from the 3rd memory location
    4,5,6,7,8,9,10,11,12,13

    This has never changed
    The write value was nowhere to me seen.. I suspect in 0,1, or 2 locations and overwritten
     
  8. Erel

    Erel Administrator Staff Member Licensed User

  9. JordiCP

    JordiCP Well-Known Member Licensed User

    There's something possibly wrong in that code for a 24C256. The use of WriteInt16 (should be writeByte) to set the address adds 2 unnecessary bytes (only 2 are needed) to the array and they are written to it. When reading, 5 bytes are sent to set the addres instead of 2, so chip internally increments this address by 3 and starts reading the 4

    Not tested, but the correct approach should be something like this :)
    Code:
    Sub WriteEEPROM (DeviceAddress As Int, EEAddress As UInt, Value As Byte) 
       
    Dim Data(3As Byte    <-- Will be 2 + data length
       
    Dim raf As RandomAccessFile
       raf.Initialize(Data, 
    True)
       
    'raf.WriteInt16(Bit.ShiftRight(EEAddress, 8), raf.CurrentPosition)   '<- writing 2 bytes each time
       'raf.WriteInt16(Bit.And(EEAddress, 0xff), raf.CurrentPosition)
        raf.WriteByte(Bit.ShiftRight(EEAddress, 8), raf.CurrentPosition)
        raf.WriteByte(
    Bit.And(EEAddress, 0xff), raf.CurrentPosition)

       raf.WriteByte(Value, raf.CurrentPosition)
       wire.WriteTo(DeviceAddress, Data)
    End Sub

    Sub ReadExtEEPROM (DeviceAddress As Int, EEAddress As UInt) As Byte
        
    Dim Data(2As Byte                  '<-- 2 bytes instead of 5, to set the address
        Dim raf As RandomAccessFile
        raf.Initialize(Data, 
    True)
        
    ' raf.WriteInt16(Bit.ShiftRight(EEAddress, 8), raf.CurrentPosition)
        ' raf.WriteInt16(Bit.And(EEAddress, 0xff), raf.CurrentPosition)
        raf.WriteByte(Bit.ShiftRight(EEAddress, 8), raf.CurrentPosition)
        raf.WriteByte(
    Bit.And(EEAddress, 0xff), raf.CurrentPosition)
        wire.WriteTo(DeviceAddress, Data)
        Delay(
    5)
        
    Dim Answer() As Byte = wire.RequestFrom(DeviceAddress,10)      ' just for fun
        Log("Answer Length  ",Answer.Length)
        
    If Answer.Length>0 Then
            
    For i=0 To Answer.Length-1
                
    Log(Answer(i))
            
    Next
            
    Return Answer(0)
        
    End If
    End Sub
     
    Erel likes this.
  10. rodmcm

    rodmcm Member Licensed User

    Well that worked!! Well spotted JordiCP I tested random locations up to 32000 on the 24LC256 (32K)
    As I was doing a read straight after a write I got some funny answers until I included a delay after the write

    So for all of you out there, with thanks to Erel and JordiCP
    Code:
    Sub WriteExtEEPROM (DeviceAddress As Int, EEAddress As UInt, Value As Byte)
        
    Dim Data(3As Byte
        
    Dim raf As RandomAccessFile
        raf.Initialize(Data, 
    True)
        raf.WriteByte(
    Bit.ShiftRight(EEAddress, 8), raf.CurrentPosition)
        raf.WriteByte(
    Bit.And(EEAddress, 0xff), raf.CurrentPosition)
        raf.WriteByte(Value, raf.CurrentPosition)
        wire.WriteTo(DeviceAddress, Data)
        Delay(
    5)
    End Sub

    '
    Sub ReadExtEEPROM (DeviceAddress As Int, EEAddress As UInt) As Byte
        
    Dim Data(2As Byte
        
    Dim raf As RandomAccessFile
        raf.Initialize(Data, 
    True)
        raf.WriteByte(
    Bit.ShiftRight(EEAddress, 8), raf.CurrentPosition)
        raf.WriteByte(
    Bit.And(EEAddress, 0xff), raf.CurrentPosition)
        wire.WriteTo(DeviceAddress, Data)
        Delay(
    5)
        
    Dim Answer() As Byte = wire.RequestFrom(DeviceAddress,1)   
        
    If Answer.Length>0 Then
            
    Return Answer(0)
        
    End If
    End Sub
     
    JordiCP likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice