|
中文乐高版MagicWand可以使用NXTG,NXC和其他平台对其操作。中文乐高版MagicWand(摇摇棒)的工作原来其实就是通过主机不断的给摇摇棒传送数据,然后在摇的过程中,不同的时刻led显示不同的数据,既可显示出图形或文字。
首先介绍一下在C环境下给摇摇棒编程的方法。
感谢BricxCC的作者,我们可以免费的使用C环境编程,也感谢他的敬业,经常更新去除BUG。向他致敬!
在nxc中已经包含了I2C的函数。通过函数,我们可以很方便的对I2C Bus操作。所以我们只需要几个简单的函数给摇摇棒送数据,就可以达到显示图形或文字的目的。
在NXC中,操作I2C的函数主要是3条,读函数,写函数和状态查询函数。因为本例只用到写函数和状态查询函数,所以先只介绍这两个。
I2CStatus(S1, nRead)
这个函数其实是LowspeedStatus(port, out bytesready) 的宏定义缩写。其作用是查询总写的状态,返回值一共有6个,分别如下,
NO_ERR 0 The operation succeeded.
STAT_COMM_PENDING 32 The specified port is busy performing a communication transaction.
ERR_INVALID_SIZE -19 The specified buffer or byte count exceeded the 16 byte limit.
ERR_COMM_CHAN_NOT_READY -32 The specified port is busy or improperly configured.
ERR_COMM_CHAN_INVALID -33 The specified port is invalid. It must be between 0 and 3.
ERR_COMM_BUS_ERR -35 The last transaction failed, possibly due to a device failure.
只有当返回只为0时,代表没有错误,方可对总线进行操作。
当查询总线正常后,就可以对总线进行写操作了,写函数为I2CWrite(S1, 1, inbuffer)
这个函数同样也是个宏定义,其原型为LowspeedWrite(S1, 1, inbuffer),其中s1代表端口,中间这个1在帮助文档中说明不清楚,说是包含的数据?我想不是,应该是应答位吧!inbuffer是一个写数组。
说明了i2c总线的函数,下面说说数组的。
示例程序用了这个函数ArrayBuild(WriteBuf, I2CAddr8574, letter);
其作用是吧I2CAddr8574加在已知数组letter之前构成一个新的数组writebuf。
最后说明一下怎么创建数组的内容。以显示“LEGO”中的“L”为例。
把L分解为从上到下8个点,从左到右也是8个点(当然也可以多几个点,字长点而已)
当显示左边的第一列点时为8个LED全亮,因为本设计用倒灌电流的设计,1为灭,0为亮。全亮为00000000(二进制数8位)。第二列为为最下一个LED亮,所以数据位11111110(0xFE)。后面以此类推。不过如果朋友看到我的示例程序的时候会发现我的程序和说明是不一样的。“L”的数组为byte L_[] = {0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0}。发现了说明没有?其实我的数据第一位为0xFF,而不是0;而第二位是0x01,也不是0xFE,那是因为我为了方便看,用了取反,大家在写程序的时候可以忽略这样的重复操作,数据显示会更快哦!
下面是我示例程序,不明白的跟帖,我尽量修改教程,以达到更多的人能明白使用方法,最近公司破产了,我有很多时间回复了,下篇讲写下用NXTG给摇摇棒编程。
- #define I2Cport S1
- #define Touch S4
- #define Touch2 S3
- #define Motor OUT_A
- // I2CAddr8574 = 0x40 for PCF8574
- // I2CAddr8574 = 0x70 for PCF8574A
- #define I2CAddr8574 0x40
- // Display patterns
- // Each byte represents a column of dots
- // Bit set to 1 means lit LED.
- // Least significant bit is at top of column.
- // Last byte must be all 0
- // Maximum number of bytes par pattern: 15
- //byte LOVE_[] = {0x70, 0xF8, 0xFC, 0x7E, 0x7E, 0x3F, 0x3F, 0x3F, 0x7E, 0x7E, 0xFC, 0xF8, 0x70};
- byte LOVE_[] = {0x70, 0x88, 0x84, 0x42, 0x42, 0x21, 0x21, 0x21, 0x42, 0x42, 0x84, 0x88, 0x70, 0};
- byte A_[] = {0x01, 0x7F, 0x89, 0x88, 0x88, 0x88, 0x89, 0x7F, 0x01, 0};
- byte B_[] = {0};
- byte C_[] = {0x7E, 0x42, 0x81, 0x81, 0x81, 0x00, 0x42, 0x24, 0};
- byte D_[] = {0};
- byte E_[] = {0xFF, 0x91, 0x91, 0x91, 0x91, 0x91, 0x81, 0x81, 0x81, 0};
- byte F_[] = {0};
- byte G_[] = {0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x89, 0x89, 0x4E, 0};
- byte H_[] = {0x81, 0xFF, 0x91, 0x10, 0x10, 0x10, 0x10, 0x10, 0x91, 0xFF, 0x81, 0};
- byte I_[] = {0x81, 0x81, 0xFF, 0x81, 0x81, 0};
- byte J_[] = {0};
- byte K_[] = {0};
- byte L_[] = {0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0};
- byte M_[] = {0xFF, 0x80, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF, 0};
- byte N_[] = {0xFF, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0xFF, 0};
- byte O_[] = {0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0};
- byte P_[] = {0xFF, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x78, 0};
- byte Q_[] = {0};
- byte R_[] = {0};
- byte S_[] = {0x62, 0x91, 0x91, 0x89, 0x89, 0x06, 0};
- byte T_[] = {0x80, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0x80, 0};
- byte U_[] = {0x80, 0xFE, 0xFE, 0x81, 0x01, 0x01, 0x01, 0x81, 0xFE, 0xFE, 0x80, 0};
- byte V_[] = {0};
- byte W_[] = {0xC0, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0xC0, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0xC0, 0};
- byte X_[] = {0x81, 0xC3, 0x42, 0x24, 0x18, 0x24, 0x42, 0xC3, 0x81, 0};
- byte Y_[] = {0};
- byte Z_[] = {0};
- void WaitTouch(void)
- {
- // Wait for pressed
- while(Sensor(Touch)==0);
- // and release
- while(Sensor(Touch)==1);
- return;
- }
- void WaitTouch2(void)
- {
- // Wait for pressed
- while(Sensor(Touch2)==0);
- // and release
- while(Sensor(Touch2)==1);
- return;
- }
- void DispLetter (const byte & letter[])
- {
- int nbytes;
- // Wait for the end of previously sent data
- while(I2CStatus(I2Cport, nbytes)==STAT_COMM_PENDING);
- // Write buffer to send to PCF8574
- byte WriteBuf[];
- ArrayBuild(WriteBuf, I2CAddr8574, letter);
- for(int i=1; i<ArrayLen(WriteBuf); i++)
- {
- WriteBuf[i] ^= 0xff;
- }
- I2CWrite(I2Cport, 0, WriteBuf);
- }
- task main ()
- {
- unsigned long t0,t1,t2;
- // Configure NXT I2C port
- SetSensorLowspeed (I2Cport);
- // Configure Touch sensor
- SetSensorTouch (Touch);
- // Start Motor, full power
- OnFwd(Motor, 100);
- while (true)
- {
- // display LEGO during each sweeps
- WaitTouch();
- /*
- //HELLO
- Wait(0);
- DispLetter(H_);
- DispLetter(E_);
- DispLetter(L_);
- DispLetter(L_);
- DispLetter(O_);
- */
- /*
- //WELCOME
- DispLetter(W_);
- DispLetter(E_);
- DispLetter(L_);
- DispLetter(C_);
- DispLetter(O_);
- DispLetter(M_);
- DispLetter(E_);
- */
-
-
- //PLEASE
- Wait(40);
- DispLetter(P_);
- DispLetter(L_);
- DispLetter(E_);
- DispLetter(A_);
- DispLetter(S_);
- DispLetter(E_);
-
-
- /*
- // while(MotorRotationCount(OUT_A) % 180 == 0)
- Wait(108);
- DispLetter(La_);
- DispLetter(Ea_);
- DispLetter(Ga_);
- DispLetter(Oa_);
- */
- }
- }
复制代码 ps:固件版本需要在1.05以上,不然有可能会提示错误!!!
|
|