Writing to EEPROM with PC via PICAXE.

rs2845

Senior Member
Hi there,

I've been trying to find an efficient way to fill my 24LC512 EEPROM. After trying to write just 126 pages (roughly) of 128 characters I've been getting a compiler error saying 'memory full'. Obviously I don't want to have to use seven or eight different programming files in order to program my eeprom.

I'm actually wondering if I can make a special 'dongle' with a picaxe to help me read/write to my eeprom, because I am eventually wanting to make a PC program to allow me to program the eeprom, as it holds the data for my alarm systems settings and device/zone labels/passwords etc. instead of eventually, I'm thinking to do this now as I've seen some success of using a tablet computer to read/write serial data via a terminal app.

I have been trying to follow the below example but cannot seem to get a successful download. I've done everything like-for-like. It just errors out and doesn't write past the first 20 bytes/characters (bits?)

http://www.eglin.plus.com/PC2EEPROM/PC2EEPROM.htm



I'd like to use a picaxe 20x2. I'm thinking I need to be able to use the hserin to store a scripted terminal session to send bytes of data every 10-15ms, which the picaxe will then write to the eeprom.


I can't seem to get started though! Can anyone assist?! Or perhaps point me in the direction of someone else's success? I've done quite a few searches but can't really find anything useful.
 

bpowell

Senior Member
A not-so-elegant way may be to use a simple loop...

1: Receive a single serial byte
2: Check if the byte is the "exit character" (255 for instance)
3: If exit character, then exit loop
4: Else, write byte to next eeprom position
5: repeat

Doing it a single byte at a time should prevent any page overruns...just an idea.

Then you just "serial out" from your PC to serial-in on the PICAXE.

I'm sure others will have a much more elegant solution!
 

westaust55

Moderator
Looking at the code and details at the link you gave, the code is sending two bytes as the EEPROM address followed by some bytes of data to the PiCAXE. The PICAXE is sending the address and a single byte of data to the EEPROM in a loop until all data bytes in a PC sent packet are written to the EEPROM.

You say "trying to follow" the info in the linked page.
Is this copy exactly or are you changing anything in hardware or code? Using a 40X2 chip?
Maybe posting a schematic and code specific to your project may help us.

Exactly what error is being reported or how are you determining the failure?
 
Last edited:

westaust55

Moderator
Now looking at the PICAXE code on a PC,
after the line:
hi2cout addresstemp,(receivedByte) 'if not, send data to address in addresstemp​
add the line
PAUSE 5​
This will accommodate the fact that for the 24LCxxx series EEPROMs whether writing one byte of several bytes at a time there is a need to give the EEPROM time to complete its internal write cycle.
The program as it is and running at 8 MHz could be feeding a byte of data out roughly every couple of milliseconds based on instructions at ~125 usec per BASIC command and the EEPROM will ignore data sent while it is performing a write cycle.
 

rs2845

Senior Member
Thanks for all your replies as always!

If I can use the above linked example I'd be happy as it already gives me a starting point for the vb program. I have copied the schematic on the website like-for-like and have successfully been able to read/write to my eeprom manually (hi2cout 0,(abcdefg)).

Basically, the errors I previously received was when the VB program showed the written values I would have ??? Showing which never actually wrote and the program just stopped writing.

I'll check everything once again and will try the pause also.
 

rs2845

Senior Member
Update: tried the 'pause 5' line... It worked! BUT now I cannot actually re-write to my EEPROM which is annoying. Wasted all evening trying to figure out why.

Now when I run the download- it will get to say 192 or 256 and the furthest was 384.

Does it take longer to overwrite an eeprom value?

How can I slow the entire program down? I've tried adding a larger pause... Just getting to grips with the Visual Basic template file for the windows application just in case I can slow down the data transfer into the picaxe.
 
Last edited:

bpowell

Senior Member
We'll need to see the code to help...however, one thing to check (and I only mention it because I've fallen prey to this so many times...) make sure you're using a WORD variable (2-BYTES) for your eeprom address...a BYTE is of course only good for 0 - 255....once you hit the limit of the byte variable, it rolls over to 0 and starts all over.
 

rs2845

Senior Member
Apologies for the delay everyone... Below is the code:


Code:
;##########################################################;######## Serial download and uploading to eeprom #########
;##########################################################


#no_table
#picaxe40x2
#terminal 9600
setfreq m8
hsersetup B9600_8, %00000111
hi2csetup i2cmaster, %10100000, i2cfast_8, i2cword
Symbol SendWaitingSignalDelay = 200
Symbol WaitForReadySignalDelay = 25
Symbol ReceiveTransmissionDelay = 75




;##########################################################
;Allocation of Variables
;##########################################################
;Word w0
;    Byte b0
;        Bits bit0
;        Bits bit1
;        Bits bit2
;        Bits bit3
;        Bits bit4
;        Bits bit5
;        Bits bit6
;        Bits bit7
;    Byte b1
;        Bits bit8
;        Bits bit9
;        Bits bit10
;        Bits bit11
;        Bits bit12
;        Bits bit13
;        Bits bit14
;        Bits bit15




;Bytes b4 to b19 (w2-w9)
symbol counter = b4 ' general counter
symbol counter2 = b5 ' temporary counter
symbol sendByte = b6 ' data byte for sending
symbol checkbyte = b7 ' byte for checking if signal received
symbol dataLength = b8 ' byte containing the data length from the PC
symbol receivedByte = b9 'for holding a downloaded byte


;Words w10 to w13
symbol address = w10 ' memory address split between:
    symbol addressMSB = b21 
    symbol addressLSB = b20
symbol addressTemp = w11 ' temporary storage of address


;##########################################################
;Allocation of Pins
;##########################################################






;##########################################################
;Constants
;##########################################################
;Symbol Datalength = 16 ;alter this to reflect length of data to be recieved
Symbol False = 0
Symbol True = 1
Symbol StartOfText = 2
Symbol EndOfText = lf
Symbol Finished = 4
Symbol Waiting = 5
Symbol Ready = 6
Symbol Failure = 7


;##########################################################
;Initial settings
;##########################################################




ptr = 0
hserflag = false


;##########################################################
sendWaitingSignal:'Send regular waiting signals @ 1us intervals
;##########################################################


hserout 0, (waiting)                'transmit waiting signal
if hserinflag = false then            'flag will be true when data received
    pause SendWaitingSignalDelay        'delay
    goto sendWaitingSignal            'loop back and send another waiting signal
endif                            'go onto next stage if hserinflag is true


;##########################################################
waitForReadySignal:'Receive ready signal and send ready signal
;##########################################################
Pause WaitForReadySignalDelay
checkbyte = @ptrinc                'get the next character
if checkbyte <> ready then            'error found - not right signal
    if hserptr = ptr then            'Check to see if buffer exhausted
        hserinflag = false        'clear flag if it is
        goto sendWaitingSignal        'and start again
    else                        'if not,
        goto waitForReadySignal        'check the next data in buffer
    endif
endif
hserout 0, (ready)                'all OK so send ready signal






;##########################################################
ReceiveTransmission: 'and store in EEPROM
;##########################################################
Pause ReceiveTransmissionDelay
;Get transmitted signal .  
checkbyte = @ptrinc                'get next byte of data
if checkByte = Finished then end        'finish if all data send
elseif checkbyte <> startOfText then     'if error in tranmission
    hserout 0, (failure)            'send error code
    goto sendWaitingSignal            'go back to start
endif


'Receive address information


datalength = 0                    'counter to control return data
addressMSB = @ptrinc                 'get address MSB
addressLSB = @ptrinc                 'get address LSB
Addresstemp = address                'copy address to temporary variable
NextCharacter:
    
;write to eeprom and screen
receivedByte = @ptrinc                'get next character
if receivedByte >10 then                'check to see if not control character
    hi2cout addresstemp,(receivedByte)    'if not, send data to address in addresstemp
    PAUSE 5                    '***TOLD TO ADD IN***
    addresstemp = addresstemp + 1        'increment addresstemp
    dataLength = dataLength + 1        'increment datalength
    'sertxd (receivedByte)             'print it to screen
elseif receivedByte = EndOfText then    'check if end of transmission flag
    goto SendTransmission            'go to next step if it does
elseif receivedByte = finished then end    'check if PC finished transmitting
else 
    hserout 0, (failure)            'send error code
    goto sendWaitingSignal            'start again if none of the above
endif
Goto NextCharacter
'sertxd (cr,lf)                    'send next line instruction to screen




    
;##########################################################
SendTransmission: 'read from EEPROM and send back to PC
;##########################################################    
    
hserout 0, (StartOfText)            'send confirmation signal
hserout 0, (addressMSB,addressLSB)         'Send address back to PC
'sertxd (#address,",")                 'print address to screen


;  Read data back from EEPROM and send to computer    
for counter = 1 to datalength            'loop for number of characters received
    Addresstemp = address + counter - 1    'calculate the position to be read from
    hi2cin addresstemp,(sendByte)        'get the byte from the address
    hserout 0, (sendByte)              'send byte to computer
'    sertxd (sendByte)             'display data  on screen
next                            'loop back to next character
'sertxd (cr,lf)                    'send next line instruction to screen    
hserout 0, (lf)                    'send confirmation signal
hserout 0, (ready)                'all OK so send ready signal
goto receiveTransmission

It's just the same as the example from my first post, only with the 'Pause 5' line in. It did actually work once- but now I can't get it to which is certainly annoying.

I wonder if this could even work with a Microchip 24LC512. The example used a different EEPROM (AT24C128B and a AT24C64B). In my text file (attached: View attachment full.txt) I have written to each page and instead of writing 128 bytes per page in a single line, I split that up into 2 lines of 64 bytes. I'm just wondering whether the VB program is sending data too fast.

Source for example: click here
 
Last edited:

westaust55

Moderator
It's just the same as the example from my first post, only with the 'Pause 5' line in. It did actually work once- but now I can't get it to which is certainly annoying.

I wonder if this could even work with a Microchip 24LC512. The example used a different EEPROM (AT24C128B and a AT24C64B). In my text file (attached: View attachment 13708) I have written to each page and instead of writing 128 bytes per page in a single line, I split that up into 2 lines of 64 bytes. I'm just wondering whether the VB program is sending data too fast.

Source for example: click here
I don't believe that the use of a Microchip 24LC512 EEPROM is the problem. Both the Atmel and Microchip i2c devices have similar timing requirements.
I suspect it could well be the comms between the PC and PICAXE gewtting out of synch but have not looked into the VB side of the project (I am no VB Guru).

it will get to say 192 or 256 and the furthest was 384. [p/quote]
Those numbers of bytes correspond with 3,4 or 6 blocks of 64 bytes.
What I find unclear is whether the number of bytes you mention are just those received by the PICAXE from the PC or what was successfully written to the EEPROM ??? :confused:

Can you try some tests to just receive multiple blocks of data from PC to PICAXE with the existing handshaking and see if that is reliable without trying to also write to the EEPROM.

If that is successful and repeatable, then you try transmitting in just 8 data byte block from PC to PICAXE and then write all 8 bytes to EEPROM.
Not as flexible as the original code but then you just define a starting EEPROM location in the word variable "address" or "Addresstemp" and then a modificed command
hi2cout addresstemp, (@ptrinc, @ptrinc, @ptrinc, @ptrinc, @ptrinc, @ptrinc, @ptrinc, @ptr)​
to write the 8 bytes before fetching the next set of data form the PC via handshaking.
 

rs2845

Senior Member
What I find unclear is whether the number of bytes you mention are just those received by the PICAXE from the PC or what was successfully written to the EEPROM ???

Well these addresses (and the corresponding data) are not written, because the program freezes. But on the very odd occasion when the program fully reaches the end of the text file, the vb program writes down all the errors into an "error" text file placed on desktop, but if the write was successful it will write down all the successful writes into a "success" file.


That "full.txt" is what I've managed to read back from the EEPROM by writing the "read back" code also available on the example site- only I have had to increase the line length in the program for it to show 64 bytes per line instead of 32. This file is identical to the text file I wrote to the EEPROM too. This is what is strange- I can read back in the PE serial terminal or even a PuTTY session without a hitch. I just cycle the power once the session is open. So it's just writing that is the problem.


I'm going to try writing in blocks of 8 when I switch my mac on and see how that goes. Might try 16 and 32 again. I'm also going to try everything on a Windows PC too as I was using Parallels on my mac with a USB>RS232 adapter. My windows laptop has a proper serial port. However- I've never experienced any issues before as this adapter was about £17

If anyone else has any of these components.. I wonder if you could try this set up to see if it works for you?
 
Last edited:

hippy

Ex-Staff (retired)
One problem with the PICAXE-side code is that it does not seem to wait for a guaranteed character received before handling that character; thus it has a poorly defined protocol and it's going to be very difficult to tell what is going wrong.

The problem could be in the PICAXE code, the PC code, or the interaction or timing between the two. The PICAXE code does not have a pure text / character-based interface so difficult to test the PICAXE code standalone using Terminal.

To do it properly IMO the PICAXE code should have a text / character-based input mechanism and have a well defined protocol. Once that's working with Terminal it is then just a matter of writing the PC side code to interact as if it were a human typing via Terminal. Of course that's easier said than done. I've looked at doing it myself but haven't had the time to commit to that.
 

Rick100

Senior Member
I tried the VB code on a 64 bit Vista PC running Visual Studio 2010 with an FTDI cable . I used a Picaxe 20X2 . It would appear to write a page then hang up .The VB program form would show the "quit responding" message . VB sometimes showed a message about "pumping" Windows and slow response . I don't know enough about VB to understand the message .
Do you want to be able to program each seeprom with it's own data or just make copies of an already programmed one . If you want to make copies , you could use a Picaxe with 2 seeproms on the I2C bus . Read 8 or 16 bytes of data at a time from the programmed one and write it to the blank .

Good Luck,
Rick
 

rs2845

Senior Member
Hi Rick. Thank you for trying it out for me. So it seems I'm not the only one experiencing issues. The next step is figuring out what's going wrong.

I'm going to try the suggested ideas from before and maybe tinker with the VB code.

Rick, I'm hoping to be able to write new data to the single eeprom every time.
 

rs2845

Senior Member
update: sending just 8 bytes at a time doesn't work either.

I tried adjusting the timings in the picaxe code, it showed the data "downloading" in the vb program but then showed an error at the end, and inside the error log was all the data I wanted to write, meaning that none of it did.

This is really annoying. I have to be able to write through a computer otherwise my project will grind to a halt. I wish the fix was simple, but it doesn't seem to be and it's driving me NUTS!!!
 
Last edited:

Rick100

Senior Member
I built a seeprom programmer that used the printer port of a 486 machine many years ago . It was programmed in VB for DOS . After seeing your initial post I started work on my own I2C seeprom programmer . For now the PC software is written in QB64 , which is a free version of Qbasic that runs on modern windows machines and supports the serial ports . The Picaxe software is for the 20X2 . Eventually it will read binary and maybe hex files but for now I used the format you showed . I have it reading the full.txt file you posted and writing it to the seeprom , 16 bytes at a time . I used my Pickit 2 to confirm the data was written , as my program doesn't dump the seeprom yet . I plan to reprogram it in VB.net after I get it working in QB64 . If your interested I could post the code for you to try . It is very basic and not robust at this point and I can't guarantee anything .

After spending many hours the past couple of days getting two machines to talk to each other , I understand your frustation . I've written a program to control a pan/tilt platform in VB.net that uses the serial port , but it only sends out a few bytes when a button is pushed . It does't have to sync up or receive anything from another device . That makes it a lot more difficult .

Good Luck,
Rick
 

westaust55

Moderator
I used my Pickit 2 to confirm the data was written , as my program doesn't dump the seeprom yet .
Here is some untested code to view the EEPROM contents over a specified range on a terminal program using the PICAXE SERTXD command. Nothing too fancy but does display the values in decimal
Just change the values in the constants in the first three SYMBOL statements to match the EEPROM slave address and memory range to view

Code:
; suitable for up to 64 kByte i2c EEPROM  ie  <= 24LC512
#no_table
#picaxe40x2
#terminal 9600
setfreq m8

; set constants
; change the next three lines to suit EPEPROM slave address and memory range to view
SYMBOL StartAddress = 0
SYMBOL EndAddress = 1023
SYMBOL EEPROMAddr = %10100000
;
;define variable alias names
symbol DataByte = b6 ' data byte for sending
symbol Temp = b7
Symbol Address = w4
hi2csetup i2cmaster, EEPROMAddr, i2cfast_8, i2cword

FOR Address = StartAddress  to EndAddress    ; loop for number of characters to view
	hi2cin addresstemp,( DataByte)		   ;get the byte from the current address
	Temp = Address // 16
IF Address = StartAddress  OR Temp = 0 THEN
   sertxd (cr,lf)
   IF TrueAddress < 10000 THEN		  ; testing for leading blanks
        SERTXD (&#8220; &#8220;)
        IF TrueAddress < 1000 THEN
             SERTXD (&#8220; &#8220;)
             IF TrueAddress < 100 THEN
                  SERTXD (&#8220; &#8220;)
                  IF TrueAddress < 10 THEN
                    SERTXD (&#8220; &#8220;)
	   ENDIF
             ENDIF
         ENDIF
     ENDIF
     SERTXD (TrueAddress,&#8221; &#8220;)		  ; display address at start of each line
ENDIF
 IF TrueAddress < 100 THEN		 ; testing for leading blanks
        SERTXD (&#8220; &#8220;)
        IF TrueAddress < 10 THEN
               SERTXD (&#8220; &#8220;)
        ENDIF	
	ENDIF
               sertxd (DataByte,&#8221; &#8220;) 			; display data  on screen
NEXT						;  loop back to next character
DO : LOOP					;  loop and wait forever
 

rs2845

Senior Member
Rick,

I'd be more than happy to give your solution a try. I don't mind a few teething issues, it's still a starting point closer to the end result than the example I found!

Please check your PM, I've forwarded you my contact details. Thank you :)

Westaus.. Your code will certainly come in handy. I'm having one final attempt at checking the VB program and the picaxe code- so this will help me see if anything has actually written.
 
Top