Tip to share...

vttom

Senior Member
I've been working on a data-collection application using a PICAXE-14M that I'd like to share with the community...

It collects data periodically in 4-bit nibbles from inputs 0-3. It then does some stuff with the data to convert it to human-readable ASCII and writes the data to an outboard memory that has a SPI interface.

The idea is that I want to dump the contents of the memory to a PC once in awhile.

My first try at this was to read the data back from the memory and transmit it to the PC using the sertxd command. Problem is, fetching the data from the memory, and getting in and out of the sertxd command adds a lot of overhead. Even though I'm clocking it at 8MHz and using a 9600baud rate, the aggregate data rate is very slow.

I then realized that I could drive the serial TX line to the PC directly from the output of the memory if I format the data and clock it appropriately.

So, now what I do is whenever I write a character into the SPI memory, I precede it with a "preamble" byte which is all 0x01. That's takes care of the stop and start bits that RS232 needs. When I want to stream the data to a PC, I put the memory in read mode and just clock it like crazy with the pwmout command, wait a certain amount of time with pause, and then shutdown the pwm.

I've been able to achieve 38400baud transfers with great reliability. I could probably go faster if I tried. And the speed-up is incredible. The old method took several minutes to transfer all the data. The new method now takes less than 2 seconds (8192 x 8 / 38400 = 1.7 seconds).
 

Technical

Technical Support
Staff member
Excellent tip. I'm sure others would like to know the exact BASIC code, pwmout values etc.
 

vttom

Senior Member
Excellent tip. I'm sure others would like to know the exact BASIC code, pwmout values etc.
The pwmout part was easy. I just brought up the PWM wizard, told it the processor clock was 8MHz, the desired PWM frequency was 38.4kHz, and the desired duty-cycle was 50%. I then pasted the result directly into my program.

I did gloss over a few important facts about transmitting data over RS232...

1) The data is sent over RS232 with "1" = low and "0" = high, so I had to invert the data before storing it in the memory (the stop bit = low and the start bit = high, so I really did store a 0x01, not the inverse). Alternatively, I could have slapped an inverter on the SPI memory's output, in which case I could have stored the data uninverted, but would have needed to invert the stop-/start-bit preamble.

2) My SPI memory assumes MSB-first, but RS232 is an LSB-first scheme. So I had to take care using my MSB-first and LSB-first SPI routines appropriately when communicating with the SPI memory.
 

moxhamj

New Member
This sounds like a brilliant bit of code. 38400 is a fantastic rate. There is a section on this forum for completed projects - would you consider writing this up with an explanation, code and a schematic? I'm sure others would find this very helpful.
 

Ralpht

New Member
I second Dr_Acula's comments.

A brilliant piece of logic there. It falls into the "why didn't I think of that" category.

Full marks to vttom.
 

MPep

Senior Member
38400 baud from a 14M!!!! WOW, Fantastic!!!

Please tell us how. And post in the finished projects section of the forum.
 

vttom

Senior Member
Your wish...

...is my command. I just posted details to the Finished Projects/Communications forum.
 

hippy

Ex-Staff (retired)
The general concept is not new ( it has been used in the past to generate video output ) but that's not said to take any accolades away from what you have achieved.

It's the first implemented application like this for a PICAXE I know of, a novel use in its own right for high-speed serial, and a very neat and ingenious use of SPI driven memory which saves no end of address counters and the like and uses minimal I/O.

Full marks, I'm very impressed. Thanks for sharing.
 

Jeremy Leach

Senior Member
Yes, I think this is very clever too. A couple of spin-off thoughts:

You might be able to use this to transmit midi messages from memory for music application - patch change etc, although not sure how useful this might be.

Also, I was just wondering about the possibility of storing an audio signal in memory using simple Delta-Modulation (1-bit sampling) then playing back at different frequencies. Probably fantasy-land ! (with ultimate aim as a picaxe-controlled Mellotron idea !).
 

hippy

Ex-Staff (retired)
This setup should be good for any uni-directional serial streaming, simply set the PWM clocking rate and out goes the bits. As long as the memory can hold all the bits and the clocking rate is available it should work great. The on-chip oscillator tolerance should be within required serial requirements, around +/-6% error in total ...

Up to 1Mbaud serial ( at 8MHz )
MIDI
DMX-512
Arbitrary IR LED pulse-streams
It mght even be possile to do video, NTSC or PAL.
1-bit audio should work ( Check Roman Black's site )

Ethernet packets would require 20MHz clocking and USB is bi-directional so they are out of scope.
 

Jeremy Leach

Senior Member
This made me think ... might be possible to use this idea to mke a simple audio 'sampler'.... use delta-modulation (only needing low-pass filter) to generate sound from FRAM data output. Drive the clock of the FRAM using a picaxe output with the TUNE command, to 'play' the sample at different frequencies. Might need to overclock picaxe and might not be very good - but only an idea !
 

vttom

Senior Member
This setup should be good for any uni-directional serial streaming (snip)
The "eureka" moment for me on this was when I realized that I could treat the external serial I/O memory as a bit bucket and put any bitstream I desired into it at a slow rate, but then play it back at a much faster rate later.

For applications where you're collecting a trickle of data that you want to intermittently retreive quickly, this seems like the way to go.

BTW - The reason I chose the RAMTROM FRAM is because it's readily available from mouser.com (one of my favorite suppliers), it is inexpensive (~US$3.50 ea.), has a low pin count, and is non-volatile.
 

hippy

Ex-Staff (retired)
I think there's a deserved satisfaction and elation to be had when such eureka moments occur, solving a number of separate problems in a very simple and elegant way. You should be very proud of what you have achieved ( I would be. "Well chuffed", to coin a British phrase ).

I was intrigued about the lifetime of the FRAM devices, because they don't have unlimited read/write/erase cycles. For the specific FRAM you chose ( FM25640 ), that's rated at a trillion (10^12) cycles, so an update once per millisecond still gives 32 years of use, probably more.

That's not a problem I would guess but it does derate rapidly going to higher update rates. If it were possible to update every microsecond, its lifetime could drop to just 11 days.

I2C-based FRAM devices seem to have a lower lifetime rating, a billion (10^9) cycles, so not so long lasting. Still, that's better than I2C EEPROM with a million (10^6) cycle flifetime and give zero length write waits.
 
Top