找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 16074|回复: 16

中文乐高版MagicWand(摇摇棒)使用教程(NXC篇)

    [复制链接]
发表于 2011-1-10 23:06:43 | 显示全部楼层 |阅读模式
中文乐高版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给摇摇棒编程。

  1. #define I2Cport S1
  2. #define Touch S4
  3. #define Touch2 S3
  4. #define Motor OUT_A
  5. // I2CAddr8574 = 0x40 for PCF8574
  6. // I2CAddr8574 = 0x70 for PCF8574A
  7. #define I2CAddr8574 0x40


  8. // Display patterns
  9. // Each byte represents a column of dots
  10. // Bit set to 1 means lit LED.
  11. // Least significant bit is at top of column.
  12. // Last byte must be all 0
  13. // Maximum number of bytes par pattern: 15


  14. //byte LOVE_[] = {0x70, 0xF8, 0xFC, 0x7E, 0x7E, 0x3F, 0x3F, 0x3F, 0x7E, 0x7E, 0xFC, 0xF8, 0x70};
  15. byte LOVE_[] = {0x70, 0x88, 0x84, 0x42, 0x42, 0x21, 0x21, 0x21, 0x42, 0x42, 0x84, 0x88, 0x70, 0};


  16. byte A_[] = {0x01, 0x7F, 0x89, 0x88, 0x88, 0x88, 0x89, 0x7F, 0x01, 0};
  17. byte B_[] = {0};
  18. byte C_[] = {0x7E, 0x42, 0x81, 0x81, 0x81, 0x00, 0x42, 0x24, 0};
  19. byte D_[] = {0};
  20. byte E_[] = {0xFF, 0x91, 0x91, 0x91, 0x91, 0x91, 0x81, 0x81, 0x81, 0};
  21. byte F_[] = {0};
  22. byte G_[] = {0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x89, 0x89, 0x4E, 0};
  23. byte H_[] = {0x81, 0xFF, 0x91, 0x10, 0x10, 0x10, 0x10, 0x10, 0x91, 0xFF, 0x81, 0};
  24. byte I_[] = {0x81, 0x81, 0xFF, 0x81, 0x81, 0};
  25. byte J_[] = {0};
  26. byte K_[] = {0};
  27. byte L_[] = {0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0};
  28. byte M_[] = {0xFF, 0x80, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF, 0};
  29. byte N_[] = {0xFF, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0xFF, 0};
  30. byte O_[] = {0x7E, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7E, 0};
  31. byte P_[] = {0xFF, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x78, 0};
  32. byte Q_[] = {0};
  33. byte R_[] = {0};
  34. byte S_[] = {0x62, 0x91, 0x91, 0x89, 0x89, 0x06, 0};
  35. byte T_[] = {0x80, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0x80, 0};
  36. byte U_[] = {0x80, 0xFE, 0xFE, 0x81, 0x01, 0x01, 0x01, 0x81, 0xFE, 0xFE, 0x80, 0};
  37. byte V_[] = {0};
  38. byte W_[] = {0xC0, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0xC0, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0xC0, 0};
  39. byte X_[] = {0x81, 0xC3, 0x42, 0x24, 0x18, 0x24, 0x42, 0xC3, 0x81, 0};
  40. byte Y_[] = {0};
  41. byte Z_[] = {0};

  42. void WaitTouch(void)
  43. {
  44.   // Wait for pressed
  45.   while(Sensor(Touch)==0);
  46.   // and release
  47.   while(Sensor(Touch)==1);
  48.   return;
  49. }

  50. void WaitTouch2(void)
  51. {
  52.   // Wait for pressed
  53.   while(Sensor(Touch2)==0);
  54.   // and release
  55.   while(Sensor(Touch2)==1);
  56.   return;
  57. }

  58. void DispLetter (const byte & letter[])
  59. {
  60.   int nbytes;
  61.   // Wait for the end of previously sent data
  62.   while(I2CStatus(I2Cport, nbytes)==STAT_COMM_PENDING);
  63.   // Write buffer to send to PCF8574
  64.   byte WriteBuf[];
  65.   ArrayBuild(WriteBuf, I2CAddr8574, letter);
  66.   for(int i=1; i<ArrayLen(WriteBuf); i++)
  67.   {
  68.      WriteBuf[i] ^= 0xff;
  69.   }
  70.   I2CWrite(I2Cport, 0,  WriteBuf);
  71. }

  72. task main ()
  73. {
  74.   unsigned long t0,t1,t2;
  75.   // Configure NXT I2C port
  76.   SetSensorLowspeed (I2Cport);
  77.   // Configure Touch sensor
  78.   SetSensorTouch (Touch);
  79.   // Start Motor, full power
  80.   OnFwd(Motor, 100);
  81.   while (true)
  82.   {

  83.     // display LEGO during each sweeps

  84.       WaitTouch();
  85.       /*
  86.       //HELLO
  87.       Wait(0);
  88.       DispLetter(H_);
  89.       DispLetter(E_);
  90.       DispLetter(L_);
  91.       DispLetter(L_);
  92.       DispLetter(O_);
  93.       */
  94.        /*
  95.       //WELCOME
  96.       DispLetter(W_);
  97.       DispLetter(E_);
  98.       DispLetter(L_);
  99.       DispLetter(C_);
  100.       DispLetter(O_);
  101.       DispLetter(M_);
  102.       DispLetter(E_);
  103.       */
  104.          
  105.          
  106.       //PLEASE
  107.       Wait(40);
  108.       DispLetter(P_);
  109.       DispLetter(L_);
  110.       DispLetter(E_);
  111.       DispLetter(A_);
  112.       DispLetter(S_);
  113.       DispLetter(E_);
  114.          
  115.       
  116.       /*
  117.      // while(MotorRotationCount(OUT_A) % 180 == 0)
  118.       Wait(108);
  119.       DispLetter(La_);
  120.       DispLetter(Ea_);
  121.       DispLetter(Ga_);
  122.       DispLetter(Oa_);
  123.       */
  124.   }
  125. }
复制代码
ps:固件版本需要在1.05以上,不然有可能会提示错误!!!
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2011-1-11 00:21:29 | 显示全部楼层
[g:02]
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-1-11 08:11:00 | 显示全部楼层
回复 dxlwf 的帖子

楼上朋友发这个表情什么意思,鄙视我?有什么指教请讲。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-1-11 08:29:14 | 显示全部楼层
勉强能看懂意思,那硬件呢?
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-1-11 08:55:48 | 显示全部楼层
= =||我在想...I2CWRITE中间的那个数字是不是代表返回数据的字节数量啊= =?因为在LABVIEW里面就需要设定返回字节的数量,好有一个BYTE READY...如果到读的时候再说明数量..可能就来不及了......仅限猜测...
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-1-11 17:38:35 | 显示全部楼层
嗯嗯,期待NXTG的方法~好的话我也去LZ呢买个~
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-1-11 18:58:49 | 显示全部楼层
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-1-11 20:37:07 | 显示全部楼层
太棒了!!brickcc终于支持了!!!
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-1-11 21:38:37 | 显示全部楼层
回复 jerryyuzhihao 的帖子

终于支持什么,i2c?一直都支持的吧。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-1-11 23:47:27 | 显示全部楼层
期待NXT-G教程
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-1-18 23:15:53 | 显示全部楼层
最近公司破产了,我有很多时间回复了
是说你不错啊!公司破产了,可你心情很好,还能做其它事情.支持!
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-4-6 16:52:10 | 显示全部楼层
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-9-24 12:53:25 | 显示全部楼层
这个程序中对马达的控制只有一句OnFwd(Motor,100)
摇到一边去就会不动了,卡在那吧
WaitTouch()中也是,两个循环,如果马达不换方向的话,按钮会被release吗

Extreme NXT中的搭建图比这个更是少了一个Touch2,
我也很奇怪,Extreme NXT中的源程序和这个完全一样,
也没有任何判断回摆的机制

当然,本搭建图纸虽然放了两个Touch Sensor,
也写了一个WaitTouch2,但实际上从没有被调用过。

自己改了改,发现摇几次就要散架了,转盘的输出臂那里很不牢靠。

是不是我对回摆没有理解对?
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2011-9-24 15:17:42 | 显示全部楼层
程序只要了一个触碰传感器,如果摇到一边就卡住,可能是结构上没有答对,应该和火车那摆臂差不多的结构。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2011-9-24 17:22:30 | 显示全部楼层
糖伯虎 发表于 2011-9-24 15:17
程序只要了一个触碰传感器,如果摇到一边就卡住,可能是结构上没有答对,应该和火车那摆臂差不多的结构。

是的,找到问题了,转轴上接的那个转盘8547中没有,自己用了个太大的,所以就卡住了。

谢谢。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2024-4-28 01:34 , Processed in 0.080867 second(s), 18 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表