50 extra IO (16 analogs) for £8


64 posts   Page 1 of 3   1, 2, 3
by gfwilliams » Fri Oct 05, 2012 3:03 pm
I thought this might be handy for anyone looking for a cheap way to get extra IO on their RasPi (or PC :) ).

I've written a JavaScript interpreter which runs on a VERY cheap board, the STM32VLDISCOVERY. It's currently £8 from Farnell and it's got bags of IO: http://uk.farnell.com/stmicroelectronics/stm32vldiscovery/stm32-value-line-discovery-kit/dp/2118806

It's all 3.3v, so no problem connecting it with the Pi.

The interpreter is here:
http://www.pur3.co.uk/espruino/

Just follow the instructions there to put it onto the STM32VLDISCOVERY board, then use the instructions below. Most stuff in 'code' boxes needs to be copy and pasted to a terminal:

We need to stop the Raspberry PI trying to use its serial port:

Code: Select all
sudo nano /boot/cmdline.txt

Remove the text 'console=ttyAMA0,115200' and 'kgdboc=ttyAMA0,115200'. Press Ctrl+X to exit, then Y then enter to confirm.

Code: Select all
sudo nano  /etc/inittab

Remove the lines (down the bottom):
Code: Select all
    #Spawn a getty on Raspberry Pi serial line
    T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Press Ctrl+X to exit, then Y then enter to confirm.

Reboot:
Code: Select all
  sudo shutdown -r now


Then install a terminal app to test with:

Code: Select all
  sudo apt-get install minicom


And finally, we want to set our user up so that we can access the serial port without having to type 'sudo'. This allows us to 'dialout' of the Raspberry Pi:

Code: Select all
  sudo usermod -a -G dialout pi


And run it:

Code: Select all
  minicom -o -b 9600 -D /dev/ttyAMA0


Connect up the STM32VLDISCOVERY board:

Code: Select all
  PI            STM32
  P1-04         5V
  P1-06         GND
  P1-08         PA10
  P1-10         PA9


For the locations, see: http://elinux.org/RPi_Low-level_peripherals
Note: On the Pi, P1-04/6/8/10 are 4 pins next to each other, down the long edge of the board. P1-02 is the pin right in the corner (don't use that one!) and P1-04 is the one next to it, P1-06 is the one after that, etc.

Now when you hit the black reset button on the STM32 board, you should see some text appear saying 'Espruino' in big letters. Sorted.

You can turn digital pins on and off using a command like digitalWrite(pin, value) - eg, writing digitalWrite("C9", 1); will turn the LED on.

Or copy and pasting the following will flash it 5 times every time you press the blue button:

Code: Select all
setWatch(function() {
  if (!digitalRead("A0")) return;
  var led=10;
  var flasher = setInterval(function() {
   led--;
   digitalWrite("C9",led&1);
   if (led<=0) clearInterval(flasher);
  }, 200);
}, "A0", true);


You can write complete JavaScript code in it - see the website http://www.pur3.co.uk/espruino/ for other stuff you can put in.

To exit the terminal app, press Ctrl-A then X, then hit enter to confirm.

So now you might want to actually control some IO from a program.

Set up serial port:

Code: Select all
stty -F /dev/ttyAMA0 9600 -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts ignbrk raw min 0 time 5

(note that raw,min + time 5 are important - they make cat only wait for 1/2 a sec for a reply)

Turn LED on:

Code: Select all
echo -ne 'digitalWrite("C9",1);\r' > /dev/ttyAMA0


Turn LED off:

Code: Select all
echo -ne 'digitalWrite("C9",0);\r' > /dev/ttyAMA0


Turn LED on, then off 1 second later - note that it returns immediately!:

Code: Select all
echo -ne 'digitalWrite("C9",1);setTimeout("digitalWrite(\"C9\",0);",1000);\r' > /dev/ttyAMA0


You can also read inputs (for instance the button) with digitalRead("A0"), as well as Analog inputs (on the A port) using analogRead("A0"):

first - to set it up not to send any 'extra' data back:
Code: Select all
echo -ne 'echo(false);\r' > /dev/ttyAMA0


and then:
Code: Select all
echo -ne 'setTimeout("print(digitalRead(\"A0\"))",100);\r' > /dev/ttyAMA0;cat /dev/ttyAMA0


This is particularly nasty - can anyone think of a better way?

As you can run JavaScript while the Pi is off doing something else, you can also do stuff like this:

Every 10th of a second, read an analog value, and store it in a running average:
Code: Select all
echo -ne 'echo(false);var a=0;var n=0;setInterval("a+=analogRead(\"A0\");n++;",100);\r' > /dev/ttyAMA0


Then at any point after, do this to read the average and zero it:
Code: Select all
echo -ne 'setTimeout("print(a/n);a=0;n=0;",100);\r' > /dev/ttyAMA0;cat /dev/ttyAMA0


Try running the last command a few times, with/without the blue button pressed.

So you could do it as a cron job, and read what the average has been over the last hour...

Anyway, hope that's interesting to someone - let me know what you think!

I'd like to find some way to get support for this so I can document it better, improve the interpreter and port it to more boards.
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by gfwilliams » Fri Oct 05, 2012 3:27 pm
Just to add, you can also control servos...

You just send it the following code:

Code: Select all
var coords = [0,0];
setInterval(function() {
 digitalPulse("A1",1,1+coords[0]);
 digitalPulse("A2",1,1+coords[1]);
},20);


And connect servos to PA1 and PA2. You can then send commands like:

Code: Select all
coords[0] = 0.5;


or:

Code: Select all
coords = [0.25,0.25];


and the servos will move the positions you give to them. Obviously you could do more interesting things (like pushing new points into an array, and then having them interpolated between).
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by joan » Fri Oct 05, 2012 3:33 pm
That looks like a very useful board. How does it compare to Arduinos?
User avatar
Posts: 4140
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by RaTTuS » Fri Oct 05, 2012 3:40 pm
it's differnt but then again so are these
http://uk.farnell.com/jsp/search/displa ... Vk-ffrdm01
1QC43qbL5FySu2Pi51vGqKqxy3UiJgukSX - Prosliver FTW
"That's not right, the badgers have moved the goalposts."
User avatar
Posts: 4159
Joined: Tue Nov 29, 2011 11:12 am
Location: North West UK
by gfwilliams » Fri Oct 05, 2012 3:46 pm
... compare to Arduinos?


The STM32VL board compares well to old Arduinos, not well to the new ARM base DUE. The STM32F4 board is only a bit more expensive, and blows even the DUE to bits :)

The issue is toolchains. Arduino is easy, but it's really difficult to find a decent Windows toolchain for ARM that is free. On Linux it's a disaster (compilers are easy, but actually setting the build up with the correct standard libraries isn't!).

That's why I wanted to make Espruino - suddenly you don't need to mess around with toolchains at all. Only problem is there are millions of ARM boards around I'd have to build for! (like FRDM, Teensy 3.0, Arduino DUE, Olimex stuff) :)
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by gfwilliams » Tue Oct 09, 2012 12:46 pm
Just to post an update, this now works on the STM32F4DISCOVERY board too. That board is much more powerful and has 80 IOs! It still only costs £10 in the UK.

You can also write code like the following:

Code: Select all
digitalWrite(["D12","D13","D14","D15"], 13);


or:

Code: Select all
var myParallel = ["A7","A6","A5","A4","A3","A2","A1","A0"];
digitalWrite(myParallel, 13);
digitalWrite(myParallel, 213);


to write to multiple pins at once.
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by davej » Mon Oct 22, 2012 6:24 pm
Had a read at your website, and want know if the following is feasable:

Connect 4 wires as outlined to get it to work

Connect another 2 wires, more below

Squirt a program down the serial line, using good old fashion cat

The sent program would contain some serial commands, amongst others [Serial1|Serial2].print(string)

What I am hoping is that the extra 2 wires connected to the RPI in combination with the print would enable me to send data back to the Raspberry PI. So, effectively one serial channel would be for control, and one for data comms.

Feasible ?
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by davej » Mon Oct 22, 2012 6:42 pm
davej wrote:Had a read at your website, and want know if the following is feasable:...
enable me to send data back to the Raspberry PI. So, effectively one serial channel would be for control, and one for data comms.

Feasible ?

Looks like the RPI only has one serial port, so I would have to wire the second STM32 serial port back via a USB/serial cable if I wanted to do this in hardware rather than software.
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by gfwilliams » Mon Oct 22, 2012 7:59 pm
Yes, as far as I know only one serial port, so if you want 2 into the raspberry pi then you'd have to use a USB-TTL converter - or you could use the Olimex STM32 board with Espruino, which is a little more expensive but which can communicate via USB (as well as 2 serial ports).

However you should be able to send both data and code down the same serial port if you wanted... using a simple 'print(...)' prints data back down the standard serial port, and if you set echo(false) then Espruino shouldn't send extra data back that might get in the way. I'm not sure, but you might be able to open the serial port in linux for reading only, and then still use cat to send commands?

If you want to send data to Espruino, just wrap it up in a function call, like: "handleData({servo1:123,servo2:12})" - that way your handleData function gets called with the ready-parsed data...

Hope that helps!
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by davej » Tue Oct 23, 2012 4:31 pm
gfwilliams wrote:Yes, as far as I know only one serial port, so if you want 2 into the raspberry pi then you'd have to use a USB-TTL converter - or you could use the Olimex STM32 board with Espruino, which is a little more expensive but which can communicate via USB (as well as 2 serial ports).

However you should be able to send both data and code down the same serial port if you wanted... using a simple 'print(...)' prints data back down the standard serial port, and if you set echo(false) then Espruino shouldn't send extra data back that might get in the way. I'm not sure, but you might be able to open the serial port in linux for reading only, and then still use cat to send commands?

If you want to send data to Espruino, just wrap it up in a function call, like: "handleData({servo1:123,servo2:12})" - that way your handleData function gets called with the ready-parsed data...

Hope that helps!


I like the idea of all of this, esp since most of what I what is low power stuff for which the GertBoard is a bit overkill.

(I think I will try and solve the dual serial port question with an USB_MIDI interface I have lying around, and since the RPI only has to read incoming data on it, all I need is a transistor and and a couple of resistors on the STM side to turn one of the UART ports into a MIDI port)

So, more questions: How fast/slow: If I wrote a tight loop to turn a digital output on and then off and then on.... how fast would it look on a scope? Would it work if connected like this to standard CMOS logic ICs (say a flip-flop) or would the combination of STM+JavaScript be too fast ?

I gather from your website that JS internally handles all the setup to treat a pin as say a ADC pin rather than a UART pin. (Inferred by the lack of special function calls.) Is this correct?

Hoping this is all positive; This could save me a lot of support chips....

Dave
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by gfwilliams » Tue Oct 23, 2012 5:00 pm
As I said above, I'm not convinced you need 2 serial ports for control - I would have thought you could do everything with a single one.

Espruino figures out what the output should be from the command you send. It's not ideal, but it's good for bodging stuff up. I might add direction control later, but I could do it in a way which didn't break existing code.

If you write the code:
[code]while (1) { digitalWrite(LED1,1); digitalWrite(LED1,0); }[/code]

You get a roughly 4.5khz square wave on the F4 board.

Hopefully as Espruino matures that speed will go up, but generally for controlling things in the real world it's still good enough. You can still do PWM with the analogWrite function, and hopefully later on I'll add an extra parameter to control the PWM frequency.
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by davej » Tue Oct 23, 2012 5:40 pm
[quote="gfwilliams"]As I said above, I'm not convinced you need 2 serial ports for control - I would have thought you could do everything with a single one
.....
You get a roughly 4.5khz square wave on the F4 board

That kind of speed is good for me; don't need faster and won't have to write a bunch of delay stuff.

Why 2 channels?

Future-proofing. For example, I could write a completely separate program (say XYZ) to read the data channel (MIDI) and XYZ would not know or care that the data comes from a STM MCU. And I could plug my MIDI interface into my other computer and run XYZ on there since it would not have to go through any specific initialisation routines. And I could replace the development board with something else, and everything would still work.

Off to go and place an order. Thanks a lot for your work, and I hope a lot of other people will also benefit from it.

Dave
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by jacksonliam » Tue Oct 23, 2012 6:57 pm
Wow, this sounds great.
I have an F4 board and one of the cheaper STM32 ones sat in the packaging. I was thinking they were amazing for the price but didn't have the time to learn to use them properly!
Its a very good idea. Do you think I could have some code looping on the F4 running an LED matrix, then send it 'frames' over serial formatted into a javascript array? Sounds like it might be slow, parsing the 'frames' into text and then back (on the F4) but not sure.

Looking at 25fps, 512 bytes per frame.
User avatar
Posts: 151
Joined: Tue Feb 07, 2012 10:09 pm
by davej » Tue Oct 23, 2012 7:29 pm
...
> Off to go and place an order.

Ordered a STM32F4. Looking forward to this.

PS: Did you use a Linux toolchain to do this ?

PPS: Was the process horrendous ? Asking because I have in the past toyed with Forth, and was also wondering how easy it would be to get something like the Io language to run on a board this size.
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by gfwilliams » Tue Oct 23, 2012 8:09 pm
For the display, I think it'd be pretty good. Espruino is pretty fast parsing arrays, and you can write to up to 64 pins at once using digitalWrite([A0,A1,A2,etc],number), so if you actually encoded the data like:
Code: Select all
image=[
0b01000010,
0b00000000,
0b11000011,
0b00111100,
];

it'd actually be way more than fast enough! I'd think it would be fine even if you did it in a more basic way though.

Worth giving a try - I'd love to see it going! What LED display did you have in mind?

Toolchain: Yes, it's all compiled in Linux. Well, I thought it was hard to get started, but I decided to have a go trying to compile Espruino for the Freescale FRDM board today, and now it seems like it was pretty easy for STM32 after all ;) Once you have got the compiler installed (codesourcery is easiest) and the linker script, you're basically sorted though.

One thing I did notice is that the stdlib uses quite a lot of RAM - so on smaller parts you could have trouble. I only use a few functions for Espruino so I just do without stdlib completely. Having said that, the F4 has enough RAM that it really won't be an issue at all!
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by gfwilliams » Wed Oct 24, 2012 2:15 pm
Hi, Just thought I'd post up that I now have an LCD driver written in JavaScript for the common 20x4s (it needs the Olimexino or F4 boards though - the VL doesn't have quite enough RAM to do much except Hello World!).

I know you can connect the 20x4s to the RPi direct, but this way you get all the IO as well...
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by davej » Wed Oct 24, 2012 3:02 pm
Is it better/preferable to downoad and compile the stlink utility directly on the Pi or on the desktop ?
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by gfwilliams » Wed Oct 24, 2012 3:06 pm
I'd use desktop - that's how I do it here, and it only takes a few seconds. Hopefully you'll have no need to use it on the Pi itself.
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by davej » Wed Oct 24, 2012 3:25 pm
gfwilliams wrote:I'd use desktop - that's how I do it here, and it only takes a few seconds. Hopefully you'll have no need to use it on the Pi itself.


Thanks. Farnell say my order has shipped, so here's to patience. Will spend the time re-reading the STM documentation.
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by gfwilliams » Thu Oct 25, 2012 3:39 pm
Cool, let me know how it goes!

I've just updated the website with the LCD driver, servo, stepper motor, and a bunch of other code examples...

http://www.espruino.com/
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by davej » Thu Oct 25, 2012 7:12 pm
davej wrote:Thanks. Farnell say my order has shipped, ...


OK, it arrived. Slapped some polymorph onto the bottom headers.

Inferred from the docs:

Find USB to mini-USB cable

Download the espruino binary

Download and compile stlink sw

Leave both CN3 jumpers on the STM32F4DISCOVERY

Cable up

Run the stlink software

Correct ?
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by gfwilliams » Thu Oct 25, 2012 9:42 pm
Yes, seems right... You need the usb that is opposite the headphone jack...
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by davej » Fri Oct 26, 2012 6:41 pm
Progress, but not success.
cksum espruino_1v13_stm32f4discovery.bin
1415999454 86868 espruino_1v13_stm32f4discovery.bin

compiled st-flash, and flashed the STM.

st-flash write espruino_1v13_stm32f4discovery.bin 0x08000000
Device connected is: F4 device, id 0x10016413
Attempting to write 86868 .......
Starting Flash write for F2/F4...
Starting verification of write complete
Flash written and verified! jolly good!

Followed instr to disable serial port.
wired up (4 wires as above)
ran minicom
But STM reset button does not bring up the espruino message

Power LED is on
LD1 blinks red at 1 sec intervals (and never turns green)
LD7 on STM (next to micro USB) is on, indicating incoming serial port.
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm
by gfwilliams » Sat Oct 27, 2012 9:28 am
Hi,

Actually it turns out the wiring was for the STM32VL, not the F4...

On the F4, the normal USART1 pins are shared with the USB - so the default was USART2.

Try:
Code: Select all
PI            STM32F4
  P1-04         5V
  P1-06         GND
  P1-08         PA3
  P1-10         PA2


And ensure minicom is running at 9600 baud...
Hope that helps!
Posts: 44
Joined: Thu Jun 14, 2012 8:29 am
Location: Cambridge
by chopc » Sun Oct 28, 2012 6:10 am
I'm having some problems with the STM32F4 board as well , noting your pin allocations in the last post, they don't seem to correspond to my F4 board :-


P1,06 is NRST not GND
P1,08 is PC0 not PA3
P1,10 is PC2 not PA2

I get no response using PA3 and PA2 ( pins P1,13 and P1,14 respectively ) is the stated possibly a confusion between the VL and F4 boards
Posts: 2
Joined: Sun Oct 28, 2012 5:59 am