幻生幻灭 发表于 2013-4-10 15:36:50

Yeelink应用之微博点阵提醒器[ENC28J60+Arduino+Matrix LED]

本帖最后由 幻生幻灭 于 2013-4-10 15:38 编辑



奋斗了两晚上,最终在张老师的帮助下实现了微博提醒器的原型。
http://v.youku.com/v_show/id_XNTM3NDQ0MjQ4.html

功能如下:
1. 自动获取IP
2. 获得微博状态并显示在点阵LED上

电路连接如图

ENC28J60与Arduino接线参考资料:arduino学习笔记26 - ENC28J60以太网模块实验
http://www.geek-workshop.com/thread-200-1-1.html

点阵电路的教程:http://www.geek-workshop.com/thread-2570-1-1.html
点阵动画的教程:http://www.geek-workshop.com/thread-2726-1-1.html

Yeelink配置图

参考资料:张老师写的 enc28j60+yeelink利用browseUrl()函数l获取开关状态
http://www.geek-workshop.com/thread-2034-1-1.html


Arduino主程序代码

//**************************************************************//
//BOXZ Matrix Eyes(Matrix 8x8 LED)
//For 74HC595 x2 (without ULN2803)
//creat by Leo 2012.11.25(http://weibo.com/leolite)
//the drive is referenced from http://www.instructables.com/id/LED-Dot-Matrix-Display-1/
//the animation is referenced from http://www.bleq.nl/arduino/   
//****************************************************************

//**********************Handbook**********************************
//How to use this?
//Just use the software named "ArduinoFrameAnimator" to export the "animation.h" file.
//Then Copy to this Tab"animation.h" and Upload.
//The main sketch don't need to change anything! The animation will loop playback itself
//Only if you want to add some action in loop(). Have fun!

/*_
_____________
|             |
|             |
|1.2.3.4.5    |
|6.7.8.9.10   |
|             |
______________

GND:1,6
5V:2,7
latchPin:3,8
clockPin:4,9
datain:5
dataout:10
*/
//****************************************************************
#include <TimerOne.h>
#include <EtherCard.h>
#include "animation.h"

//Pin connected to ST_CP of 74HC595(Pin 12)
int latchPin = 4;
//Pin connected to SH_CP of 74HC595(Pin 11)
int clockPin = 5;
////Pin connected to DS of 74HC595(Pin 14)
int dataPin = 6;

// A number indicating when to advance to the next frame
unsigned long nextImage = 0;
// A counter to know what frame we're showing
int animationIndex = 0;
// 8x8 Point temporary array
byte brightnesses;
// Matrix image frame for 8x8 LED
int M;
//------------------------------------------------------------------------


#define REQUEST_RATE 5000 // milliseconds
// ethernet interface mac address
static byte mymac[] = {
0x74,0x69,0x69,0x2D,0x30,0x31 };

// remote website name
char website[] PROGMEM = "api.yeelink.net";
char urlBuf[] PROGMEM = "/v1.0/device/xxx/sensor/xxx/";
char apiKey[] PROGMEM = "U-ApiKey: xxxxx";
byte Ethernet::buffer;   // a very small tcp/ip buffer is enough here
static long timer;
String switchStatus;
int switchint;

// called when the client request is complete
static void my_result_cb (byte status, word off, word len) {
String reply=(const char*)Ethernet::buffer + off;
switchStatus = reply.substring(reply.length()-2,reply.length()-1);
//Serial.println(reply);
Serial.print("<<< reply ");
Serial.print(millis() - timer);
Serial.println(" ms");
Serial.print("Switch Status:");
Serial.println(switchStatus);
Serial.println();
}

//---------------------------------------------------------

void setup() {
//set pins to output so you can control the shift register
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);

Serial.begin(57600);
Serial.println("DHCP Demo");

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

if (!ether.dhcpSetup())
    Serial.println("Failed to get configuration from DHCP");
else
    Serial.println("DHCP configuration done");

ether.printIp("IP Address:\t", ether.myip);
ether.printIp("Netmask:\t", ether.mymask);
ether.printIp("Gateway:\t", ether.gwip);
ether.printIp("DNS:\t", ether.dnsip);

timer = - REQUEST_RATE; // start timing out right away

}

void loop() {
ether.packetLoop(ether.packetReceive());
if (millis() > timer + REQUEST_RATE) {
    timer = millis();
    if (!ether.dnsLookup(website))
      Serial.println("DNS failed");
    ether.printIp("Server: ", ether.hisip);
    Serial.println("\n>>> REQ");
    ether.browseUrl(urlBuf, "datapoints", website,apiKey, my_result_cb);
}

if(switchStatus.charAt(switchStatus.length() - 1) =='1'){
    if(animationIndex >= animationFrames)
    {
      //restart animation index
      animationIndex = 0;
    }
    else{
      //load Delay time for Image
      nextImage = animationDelays;

      //load image(converted)
      for(int m=0; m<5; m++) {
      for(int i=0; i<64; i++) {
          brightnesses = (animation04 >> (i%4*2)) & B00000001;
          M |= (brightnesses << (i%8)) ;
      }
      }

      //Update Image
      screenUpdate(nextImage);
      animationIndex ++;

      //clear M[]
      for(int i=0; i<(8); ++i) {
      M=0;
      }
    }
}
if(switchStatus.charAt(switchStatus.length() - 1) =='0'){
    if(animationIndex >= animationFrames)
    {
      //restart animation index
      animationIndex = 0;
    }
    else{
      //load Delay time for Image
      nextImage = animationDelays;

      //load image(converted)
      for(int m=0; m<5; m++) {
      for(int i=0; i<64; i++) {
          brightnesses = (animation00 >> (i%4*2)) & B00000001;
          M |= (brightnesses << (i%8)) ;
      }
      }

      //Update Image
      screenUpdate(nextImage);
      animationIndex ++;

      //clear M[]
      for(int i=0; i<(8); ++i) {
      M=0;
      }
    }
}
}



void screenUpdate(unsigned long frametime)
{ // function to display image

    unsigned long startime=millis();
while(millis()-startime<frametime)
{
    byte row = B10000000; // row 1
    for (byte k = 0; k < 8; k++)
    {
      digitalWrite(latchPin, LOW); // open latch ready to receive data
      shiftIt(~row); // row binary number
      shiftIt(M); // LED array (inverted)

      // Close the latch, sending the data in the registers out to the matrix
      digitalWrite(latchPin, HIGH);
      row = row>> 1; // bitshift right
    }
}
}



void shiftIt(byte dataOut) {
// Shift out 8 bits LSB first, on rising edge of clock
boolean pinState;

//clear shift register read for sending data
digitalWrite(dataPin, LOW);
// for each bit in dataOut send out a bit
for (int i=0; i<8; i++) {
    //set clockPin to LOW prior to sending bit
    digitalWrite(clockPin, LOW);
    // if the value of DataOut and (logical AND) a bitmask
    // are true, set pinState to 1 (HIGH)
    if ( dataOut & (1<<i) ) {
      pinState = HIGH;
    }
    else {
      pinState = LOW;
    }
    //sets dataPin to HIGH or LOW depending on pinState
    digitalWrite(dataPin, pinState);
    //send bit out on rising edge of clock
    digitalWrite(clockPin, HIGH);
    digitalWrite(dataPin, LOW);
}
digitalWrite(clockPin, LOW); //stop shifting
}




Arduino代码(包含点阵动画程序)

paublo 发表于 2013-4-10 15:44:27

cool.字数补丁

wasdpkj 发表于 2013-4-10 16:12:56

我也做了一个微博语音加呼吸灯提醒的,你这个触发后有没有加上归零?(要不开关一直是开)

幻生幻灭 发表于 2013-4-10 17:08:56

wasdpkj 发表于 2013-4-10 16:12 static/image/common/back.gif
我也做了一个微博语音加呼吸灯提醒的,你这个触发后有没有加上归零?(要不开关一直是开)

:lol额,忘记加了。 你也是用Yeelink做的?响应快么?

xxx 发表于 2013-4-10 18:22:52

16*16能用595驱动不

wasdpkj 发表于 2013-4-10 18:55:14

RE: Yeelink应用之微博点阵提醒器

幻生幻灭 发表于 2013-4-10 17:08 static/image/common/back.gif
额,忘记加了。 你也是用Yeelink做的?响应快么?

恩,是的,yeelink是30s抓取一次,肯定快不起来

libn 发表于 2013-9-18 16:54:10

幻生幻灭 发表于 2013-4-10 17:08 static/image/common/back.gif
额,忘记加了。 你也是用Yeelink做的?响应快么?

你这是使用http协议,循环取数据,速度当然不快。不知您找到解决办法了吗?

幻生幻灭 发表于 2013-9-18 21:29:53

libn 发表于 2013-9-18 16:54 static/image/common/back.gif
你这是使用http协议,循环取数据,速度当然不快。不知您找到解决办法了吗?

我们解决不了哦,是服务器的配置问题

libn 发表于 2013-9-22 16:03:55

幻生幻灭 发表于 2013-9-18 21:29 static/image/common/back.gif
我们解决不了哦,是服务器的配置问题

您使用enc28j60模块 做过跨网段的反向控制的实验吗?

arduino连接到路由器上,可以访问外网地址,但是不知外网如何访问arduino,需要在路由器里面为 实验ip 设置nat端口映射或者dmz主机吗?

suoma 发表于 2015-4-20 17:57:09

谢谢分享学习一下
页: [1]
查看完整版本: Yeelink应用之微博点阵提醒器[ENC28J60+Arduino+Matrix LED]