概要

上一回,我们尝试使用FlashAir的GPIO与Arduino的互动来控制火车模型。这回,则使用FlashAir附带的共享内存(Shared Memory),与Arduino进行互动。
FlashAir使用command.cgi的API,进行共享内存的读入与写出。另外,Arduino参照共享内存的周期性状态,对应共享内存上的标记值,进行PWM输出,介于H Bridge来驱动火车模型车厢的马达。并且,同样介于H Bridge,驱动转向器(Point)的改向电磁石。

FlashAirによる鉄道模型制御

详细内容

在Arduino IDE中iSDIO的可使化

依照FlashAir开发者技术支持网站上所记载的操作程序,在Arduino IDE中使iSDIO扩展指令可以使用。

参照: 创建iSDIO扩展指令

FlashAir与Arduino连接

FlashAir与Arduino的连接为,SPI连接。
这回,使用开发者技术支持网站上所推荐的Seeed Studio SD Card Shield v4。

参照: Seeed Studio SD Card Shield v4

Controller

FlashAir插入Seeed Studio SD Card Shield v4时状态
(照片中的Arduino为Arduino MEGA2560互换型电子版)

Controller

电路全图


FlashAir共享内存

关于FlashAir的共享内存,揭载在FlashAir开发者技术支持网站上内存配置图内所记载的「Reserved for Vendor(01000h〜01FFFh)」之中,通过command.cgi,用户可以使用的部分为0x1000〜0x11FF的512字节。

参照: Arduino教程 / 读取卡状态

iSDIO寄存器映射结构(摘自SD规格E7部分iSDIO简化规格版本1.10)

内存地址 名称 简介 类型
00000h Command Write Register Port 写出iSDIO Command Write Data的数据端口 W/O
00001h-001FFh Reserved
00200h Response Data Register Port 读取iSDIO Command Response Data的数据端口 R/O
00201h-03FFh Reserved
00400h-005FFh Status Register iSDIO Status Register的内存区域 别表2-7
00600h-007FFh Capability Register iSDIO Capability Register的内存区域 R/O
00800h-00FFFh Reserved
01000h-01FFFh Reserved for Vendor
02000h-1FFFFh Reserved

共享内存的数据配置

这回,利用FlashAir的共享内存与Arduino进行数据传递。为此,首先需要讨论一下如何在共享内存内处理数据。
之前提到,FlashAir的共享内存可以使用到512字节,意味了可以处理较大的数据。但此回没有处理较大数据的必要。
在此,如下图表所示共享内存作为8字位的文字列配置,在FlashAir和Arduino之间传递状态数据。
关于获取状态数据的益处在「FlashAir同人誌2」上有详细记载请参考。

Controller

共享内存的数据配置

内存地址 数值范围 数据作用
0x1000〜0x1002 000〜200 0x1000为百位数,0x1001为十位数,0x1002为一位数所组成的3位数
作为3字节内存地址的数值来处理。此数值处理运行速度为000〜200。
0x1003 0 / 1 作为表示运行方向的数值。
0:右方向, 1:左方向。
(实际上,是表示与H Bridge连接的2条数值IO连线中作为HIGH的那条。)
0x1004 0 / 1 作为表示转换器(point)开通方向的数值。
0:直线, 1:拐弯(转换方向)
(实际上,是表示与H Bridge连接的2条数值IO连线中作为HIGH的那条。)
0x1005〜0x1007 不使用 为转换器(point)作预备

向FlashAir共享内存写入数据(command.cgi)

从与FlashAir进行无线局域网连接的设备(浏览器)上访问http://flashair/command.cgi?op=131&ADDR=0&LEN=8&DATA=12345678 ,可以向共享内存写入数据。在此例中,从共享内存地址0x1000开始写入了8个字节的数据「12345678」。


从FlashAir共享内存中读取数据(command.cgi)

从与FlashAir进行无线局域网连接的设备(浏览器)上访问http://flashair/command.cgi?op=130&ADDR=0&LEN=8 ,可以从FlashAir共享内存中读取数据。在此例中,从共享内存地址0x1000开始读取了8个字节的数据。


从FlashAir共享内存中读取数据(iSDIO)

对于与FlashAir相连接的Arduino,使用以下的编码,可以从FlashAir共享内存中读取数据。


#include 
const int chipSelectPin = 4; //Seed Studio SD Card Shield V4指定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;
         }
}

此编码,首先指定SD卡的Chip Select引脚的参数为与其连接的Arduino的GPIO引脚号后,与setup函数内的card class的init函数中的SPI_HALF_SPEED一起运行,进行SD卡连接的初始化。 初始化顺利行使后,Arduino的连线端口将会表示出OK提示。

与Chip Select引脚连接的GPIO引脚号,这次使用了Seed Studio SD Card Shield V4中的4号引脚,所以指定变数chipSelectPin为4。

初始化后,从loop函数内叫出iSDIO_sharedMemRead函数后,把从共享内存读取的数据保存在変数buffer_sharedMem内。 在此编码中,是从最前面的内存地址0x1000处开始读取0x08个数据后保存在変数buffer_sharedMem内的。 利用数据的时候,使用変数buffer_sharedMem。

另外,使用command.cgi往共享内存上写入数字(0〜9)时,好像是以US-ASCII编码写入到共享内存上的。 因此,数字0为2进制码的0x30(10进制:48),数字1为0x31(10进制:49)……数字9为0x39(10进制:57)。 作为数值读取数字的情况下,char型式化后,减去48就可以使文字数字和数值互换(也许还有更好的办法,我的方法比较快捷)。


int cmd_buffer;
cmd_buffer = (char)buffer_sharedMem[0] - 48;

安装操作画面

在此例子当中,按钮被按下之时通过JavaScript使配置在FlashAir内的List.htm请求上述的URL。在下面展示了通过Web浏览器显示操作画面。

按钮 作用
STOP 紧急停止按钮。为了在火车模型车厢脱轨等场合,需要立刻使其停止。
DOWN 减速。按一下后速度减10。
UP 加速。按一下后速度增10。
Left 使其行驶方向为左。
Right 使其行驶方向为右。
SW_L 往左方打开转向器方向。
SW_R 往右方打开转向器方向。
Off 全部返回初期状态。
Clear 重载画面。
TEXT表示区 作用
SPEED_STATE 表示行驶速度。在0〜200范围内表示现行驶速度。
RESULT 表示HTTP请求时的URL。(用于检测)
Controller

在iPhone上显示操作画面List.htm


<script language="javascript" type="text/javascript"> 
<!—
//函数:对于FlashAir进行HTTP通信
function flashair_get( param ){
          var request = new XMLHttpRequest();
           request.open("GET", param, false);
           request.send(null);  } 
//定义广域変数
var send_mess = "http://flashair/command.cgi?op=131&ADDR=0&LEN=8&DATA="; 

var run_speed_state = 0;		//以数值方式格纳行驶速度的変数。
var run_speed_val = "000";	//以文字串方式格纳行驶速度的変数。
var run_lr_val = "0";		//以文字串方式格纳行驶方向的変数。
var run_point_val = "0";		//以文字串方式格纳转向器开通方向的変数。

//函数:对应各指令号码更改各変数,
//要求往FlashAir共享内存写入的HTTP请求。
function isdio_send(cmd){
          switch(cmd){
		case 1:	 //紧急停止 run_speed_state 为0(数值),run_speed_val 为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 :转向 run_point_val 为1。
			(省略)
		case 21:	//控制转向point :定向 run_point_val 为0。
			(省略)
		case 30:	 //行驶方向:右方向 run_lr_val 为0。
			(省略)
		case 31:	//行驶方向:左方向 run_lr_val 为1。
			(省略)
		case 4:	 //控制行驶:加速 run_speed_state 加10(数值), run_speed_val 加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:	 //控制行驶:减速 run_speed_state 减10(数值)、run_speed_val 减10(文字串)。
			(省略)
		} 
		document.getElementById('RESULT').value = url;
	}
//-->
</script>


在操作画面List.htm中记载的JavaScript一例

安装Arduino一側

在此例中,跟随之前提示的共享内存中的数值配置,进行如流程图所示的处理。

Controller

Arduino一侧的流程图

进行试运行

接下来,进行试运行此次火车模型创作例的装置。把作为PWM输出的H Bridge的输出接到轨道上,用来转向的H Bridge的输出接到point(定向)处。此回使用的轨道为関水金属(KATO)的产品,TOMIX也可以连接。。
在照片中,Arduino与USB连接线连接是为了给Arduino供电。 另外,此照片还显示了iPad与FlashAir无线连接,并且操作画面List.htm在操作中的情景。

Controller

在youtube上公开了控制火车行驶时的视频。



应用例:制作火车模型控制器

在此例中应用介绍过的安装,试制作了火车模型控制器(也就是电源箱)。 此控制器为,Arduino UNO R3与FlashAir组合,可以控制至2个系统的PWM输出,4个转向器。 Arduino和FlashAir当然是介于共享内存进行数据传递。 因为增加了PWM输出,共享内存的数据配置扩展为如下图所示。

Controller

共享内存的数据配置的扩展图

控制画面是在FlashAir内的List.htm处由JavaScript安装。 不只是依照操作往FlashAir的共享内存上写入数据,也定期进行读取共享内存的数据,更新画面。 因此,复数的设备(Web浏览器)与FlashAir连接上后, 不管你操作任何的设备其状态,介于共享内存都能显示在所有设备的控制画面上。
就是说,一个控制器可以由复数个人操作。 在共享内存上格纳状态数据,介于此在控制Arduino等场合下, 如何改写共享内存(例如,从复数个设备上),Arduino一侧不需要有意识的必要。 这就是使用状态数据方式的益处。

用户朋友们,也请大家使用FlashAir制作自己独特的火车模型控制器吧!试试看!

arduino-sensor

电源箱外观

arduino-sensor

电源箱内部

arduino-sensor

在Web浏览器上显示FlashAir的List.htm

arduino-sensor

使用火车模型控制器控制火车模型运行

此文章为 綾瀬ヒロ(ayase hiro)先生(@ayasehiro)撰写投稿。(2015年9月18日)
如有疑问请与作者咨询。
 

返回顶部