极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 39268|回复: 15

视频+代码 arduino UNO+enc28J60+app(andriod)+开放物联网平台

[复制链接]
发表于 2013-1-7 13:28:40 | 显示全部楼层 |阅读模式
本帖最后由 laoliu1982 于 2013-1-7 13:32 编辑





视频 http://v.youku.com/v_show/id_XNDk4NjA0NzIw.html

感谢 @zcbzjx 在  http://www.geek-workshop.com/for ... thread&tid=2260 提供的教程

采用 修改以后的ethercard 库函数(添加了一个udpreply 方法让手机APP可以自己找到andriod设备)

etercard 修改后的库:


亮点:
1:app自动寻找设备。
2:arduino是server,app 控制arduino 无明显延时。


局限性:
1 现在控制需要在同一个wifi网络下面进行,暂不支持跨网段的控制,手机要用wifi 方式。
2 代码偷懒没做usrkey的验证,所以只要一个wifi下面的设备,哪个用户登陆手机app都可以控制。
3 arduino下面http数据都是明文的。



怎么用:
1 下载手机app http://open.lewei50.com/home/sitecontent/ydkhd,去我们的平台注册一个账号,靠账号登陆app(如果非不愿意注册,用户名:demo 密码:123456 也能登陆,但是这样会影响我们以后更新功能的积极性哈)。
2 把代码找一个arduono+enc28J60下载进去(需要先用 更新 s\arduino-1.0.1\libraries\ethercard 的内容,不放心可以比较着看一下)。
3 找一个灯插在一个enc28J60 没用的引脚上面, 修改const int ledPin = 8;
4 通过手机就可以控制了。

如果你对细节感兴趣,可以看这篇文档:

再说两句废话:欢迎大家使用我们的乐联网开放平台,欢迎提意见,建设性意见会有奖励哈(比如说生成vip用户啥的{:soso_e102:} ),欢迎关注@乐为物联  技术支持群:59162154   我们的平台介绍:open.lewei50.com


代码:代码里面最后一段属于向公网平台提交测试数据,如果wifi网络没有接入公网或者不打算提交数据,可以删除 if (millis() > timer) {} 里面的内容。


  1. // Simple demo for feeding some random data to Pachube.
  2. // 2011-07-08 <[email][email protected][/email]> [url]http://opensource.org/licenses/mit-license.php[/url]

  3. #include <EtherCard.h>
  4. byte Ethernet::buffer[700];
  5. // change these settings to match your own setup
  6. #define FEED    "5942"
  7. #define APIKEY  "xxxxxx1ca57a7c8"

  8. // ethernet interface mac address, must be unique on the LAN
  9. byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

  10. char website[] PROGMEM = "open.lewei50.com";
  11. const int ledPin = 8;


  12. char* on = "ON";
  13. char* off = "OFF";
  14. char* statusLabel;
  15. char* buttonLabel;
  16. char*udpReply="{"deviceName":"01","username":"laoliu1982","port":80,"api":"api","requestType":"get"}";



  17. #define gPB ether.buffer
  18. #define UDP_DP_HIGH 36
  19. #define UDP_DP_LOW 37
  20. #define DSTPORT_HIHG 0x26
  21. #define DSTPORT_LOW 0xe7


  22. int x=1;
  23. int sensorValue = 0;
  24. int sensorPin = A0;


  25. uint32_t timer;
  26. Stash stash;

  27. void setup () {
  28.   Serial.begin(9600);
  29.   Serial.println("\n[webClient]");

  30.   pinMode(ledPin, OUTPUT);
  31.   digitalWrite(ledPin, LOW);
  32.   buttonLabel = "0";

  33.    if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
  34.      Serial.println( "Failed to access Ethernet controller");
  35.   else
  36.     Serial.println("Ethernet controller initialized");

  37.   if (!ether.dhcpSetup())
  38.     Serial.println("DHCP failed");

  39.   ether.printIp("IP:  ", ether.myip);
  40.   ether.printIp("GW:  ", ether.gwip);  
  41.   ether.printIp("DNS: ", ether.dnsip);  

  42.   if (!ether.dnsLookup(website))
  43.     Serial.println("DNS failed");
  44.    
  45.   ether.printIp("SRV: ", ether.hisip);
  46.     Serial.println("\n webClient setup end");
  47. }


  48. void loop () {
  49. word len = ether.packetReceive();
  50. word pos = ether.packetLoop(len);

  51.   if(len)
  52.   {

  53.       if(gPB[IP_PROTO_P]==IP_PROTO_UDP_V)
  54.       {

  55.         if((gPB[UDP_DP_HIGH]==DSTPORT_HIHG)&&(gPB[UDP_DP_LOW]==DSTPORT_LOW))
  56.         {
  57.           Serial.println("---Received an udp 9959 packet---");
  58.        //  ether.sendUdp(udpReply,strlen(udpReply),60000,(gPB + IP_SRC_P),9960);
  59.          
  60.           ether.leweiUdpReply(udpReply,strlen(udpReply),9960);   
  61.             
  62.         }
  63.       
  64.          
  65.       }
  66.    
  67.    }
  68.   if(pos)
  69.   {
  70.     Serial.print("len:");
  71.     Serial.println(len);
  72.    
  73.      if(strstr((char *)Ethernet::buffer + pos, "&f=getAllSensors") != 0)
  74.      {
  75.        Serial.println("Received GetAllSensor command");
  76.        BufferFiller bfill = ether.tcpOffset();
  77.        bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
  78.         "Content-Type: text/html\r\n Pragma: no-cache\r\n\r\n"
  79.       "{"successful":true,"message":null,"data":[{"id":"1","type":"jdq","name":"s1","value":"$S","status":"ok"}]}"),buttonLabel);
  80.      ether.httpServerReply(bfill.position());
  81.      }
  82.      if(strstr((char *)Ethernet::buffer + pos, "&f=updateSensor&p1=1&p2=0") != 0)
  83.      {
  84.        Serial.println("Received OFF command");
  85.        BufferFiller bfill = ether.tcpOffset();
  86.        bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
  87.         "Content-Type: text/html\r\n Pragma: no-cache\r\n\r\n"
  88.       "{"data":{"id":"1","type":"jdq","name":"s1","value":"0","status":"ok"},"successful":true,"message":null}"));
  89.      ether.httpServerReply(bfill.position());
  90.            digitalWrite(ledPin, LOW);
  91.            buttonLabel="0";
  92.      }  
  93.       if(strstr((char *)Ethernet::buffer + pos, "&f=updateSensor&p1=1&p2=1") != 0)
  94.      {
  95.        Serial.println("Received ON command");
  96.        BufferFiller bfill = ether.tcpOffset();
  97.        bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
  98.         "Content-Type: text/html\r\n Pragma: no-cache\r\n\r\n"
  99.       "{"data":{"id":"1","type":"jdq","name":"s1","value":"1","status":"ok"},"successful":true,"message":null}"));
  100.      ether.httpServerReply(bfill.position());
  101.            digitalWrite(ledPin, HIGH);
  102.            buttonLabel="1";
  103.      }     
  104. }
  105.   
  106.   if (millis() > timer) {
  107.     //timer = millis() + 10000;
  108.     timer = millis() + 3000;
  109.      sensorValue = analogRead(sensorPin);   
  110.     //Serial.println(x);
  111.     Serial.println(sensorValue);
  112.     // generate two fake values as payload - by using a separate stash,
  113.     // we can determine the size of the generated message ahead of time
  114.     x=x+1;
  115.     byte sd = stash.create();
  116.       stash.print("[{"Name":"s1","Value":");
  117.       //stash.print((word)x);
  118.       stash.print((word)sensorValue);
  119.          stash.print("},{"Name":"T1","Value":");
  120.          stash.print((word)x);
  121.        stash.println("}]");

  122.     stash.save();
  123.    
  124.     // generate the header with payload - note that the stash size is used,
  125.     // and that a "stash descriptor" is passed in as argument using "$H"



  126.        Stash::prepare(PSTR("POST /api/V1/Gateway/UpdateSensors/01 HTTP/1.1\r\n"
  127.                       "Host: open.lewei50.com\r\n"
  128.                       "Content-Length: $D\r\n"
  129.                       "userkey: $F\r\n"
  130.                       "\r\n"
  131.                       "$H"),stash.size(), PSTR(APIKEY),sd);
  132.               
  133.     // send the packet - this also releases all stash buffers once done
  134.     ether.tcpSend();
  135.   }
  136. }


复制代码


   

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

评分

参与人数 1 +1 收起 理由
幻生幻灭 + 1 感谢分享

查看全部评分

回复

使用道具 举报

发表于 2013-1-7 14:53:00 | 显示全部楼层
视频就讲了个无线控制led???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-1-7 14:55:00 | 显示全部楼层
视频只是演示了一下功能,啥都没讲。
回复 支持 反对

使用道具 举报

发表于 2013-1-7 15:24:40 | 显示全部楼层
不错,我也尝试下
回复 支持 反对

使用道具 举报

发表于 2013-1-7 20:52:10 | 显示全部楼层
挺好的物联网应用,好像微博跟你聊过天~ 有三个想法
1. 实时性如何? 能否作为小车远程控制界面。进阶的话加入视频功能。界面参考:http://www.geek-workshop.com/thread-2854-1-1.html


2. 数据库配置与更新
例如:用户可以新建数据项。例如参数01=0x10,参数02=0xFF,参数03=3A
每个参数有用户组访问和修改授权,用户组等自定义长度的参数
然后任意用户可用Arduino对其访问,授权用户可以修改参数。也支持多用户访问一个数据
数据传输形式举例:[用户(0xF)][用户组(0xF)][权限(0xF)][参数(0XFF)][数值(0xFF)] = "101A102"

3. 提供高级功能面板
用户可以自定义输入,逻辑关系,输出之间的关系。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2013-1-7 21:00:36 | 显示全部楼层
还没有以太网卡,期待更多的应用
回复 支持 反对

使用道具 举报

发表于 2013-1-8 09:03:33 | 显示全部楼层
好文章啊!!!!顶一个!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-1-8 09:09:03 | 显示全部楼层
幻生幻灭 发表于 2013-1-7 20:52
挺好的物联网应用,好像微博跟你聊过天~ 有三个想法
1. 实时性如何? 能否作为小车远程控制界面。进阶的话 ...

是啊,元旦前去了大连好几趟, 呵呵。

网内实时性应该没任何问题,直接arduino作为server接收手机http get 操作。瓶颈应该就是arduino的处理能力了。用wireshark可以看到每个包之间的延迟。 下一步就会放一个小车+机械手的例子出来了。

暂定的控制分为开关控制和值控制,协议基本一致,就是app会对应不同的操作界面。

对于一个操作需要多个参数的,暂时还没有考虑。

回复 支持 反对

使用道具 举报

发表于 2013-1-8 09:58:48 | 显示全部楼层
laoliu1982 发表于 2013-1-8 09:09
是啊,元旦前去了大连好几趟, 呵呵。

网内实时性应该没任何问题,直接arduino作为server接收手机http ...

Arduino虽然编程方便,但的确有瓶颈问题,很多时候wifi和以太网模块都是大材小用。
如果上位机APP做的好一点(例如支持按键自定义),可以直接用wifi模块自带的IO来驱动小车的

参考
http://www.geek-workshop.com/thread-1996-1-1.html
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-1-8 12:24:51 | 显示全部楼层
本帖最后由 laoliu1982 于 2013-1-8 12:30 编辑

测了一下,跨网也可以控制,只要你设备端(arduino)上面的wifi能得到一个公网地址。
步骤有点麻烦,会在后面的版本里面修改一下自动寻址的机制。如果愿意先玩一下的,可以试试。

步骤如下:找到路由器的 虚拟服务器(或类似选项),把DHCP出来的arduino地址指定进去,端口号80。


修改API地址为 公网IP地址(从路由器运行状态里面看)


别再点查找可控设备了,直接点列出可控传感器

可以把手机wifi关掉,直接拿3G或者GPRS试一下。

实验结果:大连控制北京,只要是wifi接入的,还是看不到什么延时。但是用gprs或者3g,延时比较明显有1S-2S。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2013-2-20 15:00:54 | 显示全部楼层
支持物联网
回复 支持 反对

使用道具 举报

发表于 2013-5-26 21:28:15 | 显示全部楼层
这个回头要好好做一下实验
回复 支持 反对

使用道具 举报

发表于 2013-5-26 21:52:17 | 显示全部楼层
ENC28J60价格很便宜,但是性能上不算很稳定。对比过W5100,还是w5100要更稳定些。
另外,在这种应用中,用UDP比用TCP可靠和稳定。
采样率要求非常高的场合下,也需要变换下模式。
回复 支持 反对

使用道具 举报

发表于 2013-6-16 00:01:13 | 显示全部楼层
好好跟樓主學習~~~
回复 支持 反对

使用道具 举报

发表于 2014-4-6 10:37:57 | 显示全部楼层
这教程不够详细,玩不转呢!
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-27 09:13 , Processed in 0.049204 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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