Contributor: ayase hiro
Latest update: March 2016
Previously I showed how to control a model railway with Arduino using the GPIO of the FlashAir. This time I
am using
the shared memory of the FlashAir.
On the FlashAir command.cgi is used to read and write shared memory.
The Arduino checks the shared memory and depending on the value of the flags in the shared memory it will
sets
the PWM output to drive the motor of model railway vehicle through a full-bridge driver.
We can also control the electromagnet at the switch point through a full-bridge driver.
First, follow the steps that have been posted on the FlashAir Developers site, so that you can use the iSDIO extended command in Arduino IDE.
ref. Creating the iSDIO extended command
Regarding connection of FlashAir and Arduino, we'll connect the SPI.
This time, we use the Seeed Studio SD Card Shield v4, which is also recommended by the Developers site.
ref. Seeed Studio SD Card Shield v4
FlashAir in Seeed Studio SD Card Shield v4
(the Arduino in the photo, is Arduino MEGA2560 compatible board)
Full circuit diagram
There is 512 bytes of shared memory at 0x1000~0x11FF that the user can use with command.cgi. The remaining "Reserved for Vendor (01000h〜01FFFh)" areas listed in the memory maps that are posted on the FlashAir Developers site.
ref. Arduino tutorial / Reading of the card status
Memory Map of iSDIO registers (Excerpt from SD Specifications Part E7 iSDIO Simplifed Specification Version 1.10)
Address | Name | Short Description | Type |
---|---|---|---|
00000h | Command Write Register Port | Data Port to write the iSDIO Command Write Data | W/O |
00001h-001FFh | Reserved | ||
00200h | Response Data Register Port | Data Port to read the iSDIO Command Response Data | R/O |
00201h-03FFh | Reserved | ||
00400h-005FFh | Status Register | Memory Area for iSDIO Status Register | Table2-7 |
00600h-007FFh | Capability Register | Memory Area for iSDIO Capability Register | R/O |
00800h-00FFFh | Reserved | ||
01000h-01FFFh | Reserved for Vendor | ||
02000h-1FFFFh | Reserved |
Arduino is exchanging data with the FlashAir using a shared memory of FlashAir so we need to consider how to
exchange
the data in shared memory.
As described above, shared memory of FlashAir is 512 bytes so you can use a lot of data. However, it is not
necessary
to use lots of data.
The shared memory will exchange the status between the FlashAir and Arduino using an 8-byte string
allocation.
Data allocation of shared memory
Address | Value Range | Data Specification |
---|---|---|
0x1000〜0x1002 | 000〜200 | Operate the value of 3 bytes address to three digits number, as 0x1000 is the three-digit number, 0x1001 is the two-digit number, 0x1002 is the one-digit number.Running speed to be operated on this data is 000-200. |
0x1003 | 0 / 1 | Motor direction.
0: Right. 1: Left. |
0x1004 | 0 / 1 | Indicating the value of Switch point(rail open direction).
0:Straight. 1: Branch. |
0x1005〜0x1007 | unused | Preliminary for switch point |
From a browser that can connect to the FlashAir, you can write data to shared memory by accessing a URL such
as
http://flashair/command.cgi?op=131&ADDR=0&LEN=8&DATA=12345678
.
From a browser that can connect to the FlashAir, you can write data to shared memory by accessing a URL such
as
http://flashair/command.cgi?op=130&ADDR=0&LEN=8
,you can read data to the shared memory. In this
example, you
can read the data of 8 bytes from the shared memory address 0x1000.
Like the following code in the Arduino connected to the FlashAir, you can read the data in the shared memory.
#include <utility/Sd2CardExt.h>
const int chipSelectPin = 4; //Seed Studio SD Card Shield V4 specifies to the pin of No.4.
Sd2CardExt card;
uint8_t buffer_sharedMem[8];
void setup() {
if (card.init(SPI_HALF_SPEED, chipSelectPin)) {
Serial.print(F("OK\n"));
}
}
boolean iSDIO_sharedMemRead() {
memset(buffer_sharedMem, 0, 0x08);
if (!card.readExtMemory(1, 1, 0x1000, 0x08, buffer_sharedMem)) {
return false;
}
}
First specify SPI_HALF_SPEED and the GPIO pin number of Arduino that connects to the Chip Select pin of the
SDcard as the
argument to the init function of the card class setup function. Running the code initializes the SD card
connection.
When the initialization is successful, "OK" will be displayed output to the serial port of the Arduino.
On the Seed Studio SD Card Shield V4 the GPIO pin number to be connected to the Chip Select pin is 4, so we
set chipSelectPin
variable to 4.
After initialization, when the iSDIO_sharedMemRead function is called from the loop function it will store
the data
read from the shared memory to the variable buffer_sharedMem. In this code, it reads a data block of 8-bytes
from
the start address of 0x1000. When you use the data, you can select the variable buffer_sharedMem.
By the way, if you write a single-byte numbers (0-9) in the command.cgi to shared memory, it seems that
shared memory
will be written in US-ASCII code. For this reason, the number 0 is binary code 0x30 (decimal 48), the number 1
is
0x31 (decimal 49)... number 9 is 0x39 (decimal 57). If you want to read a single-byte numbers as a numeric
value,
cast to char type and you can convert number characters and numbers. There may be a betterway to handle this,
but
this is a quick method.
int cmd_buffer;
cmd_buffer = (char)buffer_sharedMem[0] - 48;
Request the above URL when the user presses any button with javaScript in List.htm was set in the FlashAir. The image displaying the operation screen on the Web browser is shown below.
Button | Behavior and Roles |
---|---|
STOP | Emergency stop button. Such as when the model train derails in order to stop immediately. |
DOWN | Slow down. Speed -10 at once pressed down. |
UP | Speed up. Speed +10 at once pressed down. |
Left | The running direction to the left. |
Right | The running direction to the right. |
SW_L | Switch Point( rail open direction ) is to the left. |
SW_R | Switch Point( rail open direction ) is to the right. |
Off | Reset all to the initial state. |
Clear | To reload the screen. |
Textarea | Behavior and Roles |
---|---|
SPEED_STATE | Indicating the running speed. Current running speed is in the 0 to 200. |
RESULT | To show the URL when HTTP requested.(For debugging) |
Operation screen List.htm viewed on iPhone
<script language="javascript" type="text/javascript">
<!—
//Function: HTTP communication to FlashAir
function flashair_get( param ){
var request = new XMLHttpRequest();
request.open("GET", param, false);
request.send(null); }
//Global variable definition
var send_mess = "http://flashair/command.cgi?op=131&ADDR=0&LEN=8&DATA=";
var run_speed_state = 0; //To store the running speed as number.
var run_speed_val = "000"; //To store the running speed as string.
var run_lr_val = "0"; //To store the running direction as string.
var run_point_val = "0"; //To store the point open direction as string.
//Function : to change in accordance with the various variables in the command number,
//To request a HTTP request to write to the shared memory of FlashAir.
function isdio_send(cmd){
switch(cmd){
case 1: //Emergency stop run_speed_state to 0, run_speed_val to 0.
run_speed_state = 0;
run_speed_val = "000";
document.getElementById('SPEED_STATE').value = run_speed_state;
url = send_mess + run_speed_val + run_lr_val + run_point_val + “000”;
flashair_get(url);
break;
case 20: //Point control:Curve (branch ) direction run_point_val to 1.
(approx.)
case 21: //Point control:Linear direction run_point_val to 0.
(approx.)
case 30: //Running direction:Right direction run_lr_val to 0.
(approx.)
case 31: //Running direction:Left direction run_lr_val to 1.
(approx.)
case 4: //Running control:speed up run_speed_state to +10, run_speed_val to +10.
run_speed_state = run_speed_state + 10;
if(run_speed_state > 200){
run_speed_state = 200;
break;
}
run_speed_val = ( '00' + run_speed_state ).slice( -3 );
document.getElementById('SPEED_STATE').value = run_speed_state;
url = send_mess + run_speed_val + run_lr_val + run_point_val + “000”;
flashair_get(url);
break;
case 5: //Running control:Slow down run_speed_state to −10, run_speed_val to −10.
(approx.)
}
document.getElementById('RESULT').value = url;
}
//-->
</script>
Example of javaScript described in List.htm of operation screen
In this case, according to the data allocation of the shared memory shown earlier, Do the processing, such as in the flowchart of FIG.
Flowchart of Arduino side
So, let's hook up the Arduino to the model railway set. First, the output of the full-bridge driver for the PWM output is connected to the line and then the output of the full-bridge driver is connected to the switch point. We are using a Kato Precision Model Railroad set but you can connect an Arduino in the same way to other model railways such as Tommy Tech.
The USB cable is connected to the Arduino as it is the power supply. The iPad connected to the FlashAir in the photo is displaying the operation screen List.htm.
The train operation has been published in this video:
By applying the implementation introduced in this case, we tried to produce a model railroad controller (so-called power pack). The controller, in combination with the Arduino UNO R3 and FlashAir, was capable of controlling the PWM output up to 2 systems, and the switch up to 4. Of course, Arduino and FlashAir is doing the exchange of data through the shared memory. Since increasing the PWM output, The data allocation of shared memory has extended as shown in the figure.
Operation screen List.htm viewed on iPhone
Control screen, has been implemented in javaScript to List.htm in the FlashAir. Not only writes the data in
response to the
operation in the shared memory of FlashAir, read the data of shared memory regularly, then update the screen.
Therefore, when you connect from a plurality of terminals (Web browser) to FlashAir, the state of operating
in either
of the terminals will be displayed, reflected in all of the control screen through the shared memory.
In short, it was able to operate by one controller from few persons. Stores the status (state) data in the
shared
memory, through this, by the control such as in the Arduino, Arduino side does not need to be aware of how to
rewrite
the Shared memory (for example, from a plurality of terminals). this is the merit of the system using the status
(state)
data.
Everyone, please try to manufacture the original model railway controller using the FlashAir.
Outside of Power Pack
Inside of Power Pack
List.htm of FlashAir viewed in Web browser
Viewing model railway operations using the model railway controller