roc2

  • 2019-06-22
  • 发表了主题帖: 零知开源分享-Bad Apple应用于零知开发板

    “有屏的地方就有Bad Apple”,现在我们零知开发板上也移植了这个Bad Apple,使用的是SD卡存储,OLED显示画面,主要是为了大家熟悉下OLED和SD卡这两个常用模块的应用。零知开发板刚好有两个硬件SPI接口,因此在这里两个设备都是使用的硬件SPI,速度大概是10兆,因此效果还不错。 1、硬件准备 (1)零知标准板 (2)OLED-ssd1036 (3)SD卡读写模块  2、电路连接 OLED需要把MOSI,SCLK这两根线连接到SPI2对应的脚上(34,32),SD卡模块使用SPI1接口,接线如下: 很简单的啦: 3、软件代码 程序很简单,就是SD卡上文件的读取,然后是OLED的图片显示。 说明:这里我使用的是BMP图片格式,较为简单,图片属性如下: 可使用PS软件进行批量更改图片为单色BMP格式。 代码如下: /********************************************************** * 文件: badapple_oled.ino by 零知实验室 * -^^- 零知开源,让电子制作变得更简单! -^^- * 时间: 2019/06/13 19:20 * 说明: ************************************************************/ #include <SD.h> #include <Adafruit_SSD1306.h> //sd卡使用spi1 //oled使用spi2 #define OLED_DC 1 #define OLED_CS 2 #define OLED_RESET 0 Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); const int chipSelect = SS; #define BUFF_SIZE 1086 unsigned char buff[BUFF_SIZE] = {0}; //Lingzhi logo static const unsigned char pic[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0x80, 0x7f, 0xdf, 0xff, 0xfd, 0xff, 0xff, 0xbf, 0xfe, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0x80, 0x7f, 0xde, 0x3f, 0xfd, 0xff, 0xe3, 0x3f, 0xfe, 0x7f, 0xff, 0xff, 0xe0, 0xf0, 0x3f, 0xff, 0xd1, 0x7f, 0xdc, 0x3f, 0xe0, 0x1f, 0xe3, 0x3f, 0xf0, 0x0f, 0xff, 0xff, 0xc1, 0xf8, 0x3f, 0xff, 0x80, 0x7f, 0xc0, 0x1f, 0xc0, 0x1f, 0xf3, 0x3f, 0xf0, 0x0f, 0xff, 0xff, 0xc3, 0xfc, 0x3f, 0xff, 0x80, 0x3f, 0xc0, 0x9f, 0xcf, 0x9f, 0xfa, 0x1f, 0xf7, 0xef, 0xff, 0xff, 0x87, 0xfe, 0x1f, 0xff, 0x91, 0x3f, 0xc4, 0x9f, 0xce, 0xdf, 0xea, 0x5f, 0xf7, 0xef, 0xff, 0xff, 0x87, 0xff, 0x1f, 0xff, 0x80, 0x3f, 0xc4, 0x9f, 0xce, 0xdf, 0xea, 0xcf, 0xf0, 0x0f, 0xff, 0xff, 0x8f, 0xff, 0x1f, 0xff, 0x80, 0x3f, 0xd4, 0x9f, 0xf2, 0xff, 0xe8, 0xcf, 0xf0, 0x0f, 0xff, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x80, 0x3f, 0xd4, 0x9f, 0xf8, 0xff, 0xe8, 0x0f, 0xf8, 0xdf, 0xff, 0x8f, 0x1f, 0xff, 0x8f, 0xff, 0x80, 0x3f, 0xe4, 0x9f, 0xf8, 0xff, 0xea, 0x1f, 0xfd, 0xbf, 0xff, 0x07, 0x1f, 0xff, 0x8f, 0xff, 0xf3, 0xff, 0xe4, 0x9f, 0xe6, 0xff, 0xeb, 0xff, 0xf9, 0x9f, 0xfe, 0x03, 0x1f, 0xbf, 0xcf, 0xff, 0xe1, 0xff, 0xc0, 0x9f, 0xe6, 0xff, 0xe3, 0x7f, 0xfb, 0x9f, 0xfe, 0x03, 0x3f, 0x0f, 0xc7, 0xff, 0xc0, 0xff, 0xc0, 0x9f, 0xf6, 0xff, 0xe3, 0x4f, 0xf8, 0x1f, 0xfc, 0x00, 0x3e, 0x07, 0xc7, 0xff, 0x8c, 0x3f, 0xe4, 0x9f, 0xfe, 0xff, 0xf8, 0x4f, 0xf8, 0x0f, 0xfc, 0x00, 0x3c, 0x07, 0xc7, 0xff, 0x9a, 0x3f, 0xe4, 0x9f, 0xc0, 0x1f, 0xf8, 0x1f, 0xfa, 0x6f, 0xf8, 0x70, 0x3c, 0x03, 0xe7, 0xff, 0x93, 0x3f, 0xe4, 0x9f, 0xc0, 0x1f, 0xfa, 0x1f, 0xfe, 0x7f, 0xf8, 0xf8, 0x7c, 0x03, 0xe7, 0xff, 0xc0, 0xff, 0xe4, 0x9f, 0xe8, 0xbf, 0xe2, 0x1f, 0xf0, 0x0f, 0xf8, 0xf8, 0x78, 0x03, 0xe7, 0xff, 0xc0, 0xff, 0xe4, 0x9f, 0xfc, 0xff, 0xe2, 0x1f, 0xf0, 0x0f, 0xf9, 0xfc, 0x78, 0x03, 0xe7, 0xff, 0xfc, 0xff, 0xc0, 0x9f, 0xf8, 0x7f, 0xfa, 0xdf, 0xfa, 0x5f, 0xf1, 0xfc, 0x78, 0x01, 0xe3, 0xff, 0xe1, 0xff, 0xc8, 0x9f, 0xf0, 0x3f, 0xfb, 0xdf, 0xfe, 0x7f, 0xf1, 0xfc, 0x78, 0x01, 0xe3, 0xff, 0xe1, 0xff, 0xd8, 0x9f, 0xe3, 0x1f, 0xfb, 0x9f, 0xfe, 0x7f, 0xf1, 0xcc, 0x70, 0x41, 0xe3, 0xff, 0xe0, 0xff, 0xdc, 0x1f, 0xe7, 0x9f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf1, 0x8e, 0x70, 0xe1, 0xe3, 0xff, 0xfc, 0xff, 0xdc, 0x1f, 0xef, 0xdf, 0xf0, 0x0f, 0xf0, 0x0f, 0xf3, 0x8e, 0x70, 0xe1, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x70, 0xe1, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x70, 0xe1, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x70, 0xe1, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8e, 0x70, 0xe1, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8e, 0x70, 0x61, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xdc, 0x78, 0x01, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x78, 0x01, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfc, 0xf8, 0x01, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfc, 0xf8, 0x03, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0x03, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x70, 0xfc, 0x03, 0xe7, 0xff, 0xbf, 0xbd, 0xdf, 0x1f, 0x0f, 0x77, 0xbe, 0xff, 0x3e, 0x1f, 0xfc, 0x20, 0xfc, 0x07, 0xe7, 0xff, 0xbf, 0xb9, 0xde, 0x1f, 0x07, 0x77, 0xbe, 0xff, 0x3e, 0x0f, 0xfc, 0x01, 0xfe, 0x07, 0xc7, 0xff, 0xbf, 0xb9, 0xde, 0x0f, 0x07, 0x77, 0xbe, 0xff, 0x3e, 0x4f, 0xfc, 0x01, 0xfe, 0x0f, 0xc7, 0xff, 0xbf, 0xb8, 0xde, 0xef, 0xef, 0x77, 0xbe, 0xff, 0x3e, 0xef, 0xfe, 0x03, 0xff, 0x1f, 0xc7, 0xff, 0xbf, 0xb8, 0xde, 0xef, 0xcf, 0x77, 0xbe, 0xff, 0x1e, 0xef, 0xfe, 0x03, 0xe7, 0xff, 0xcf, 0xff, 0xbf, 0xb8, 0xdc, 0xff, 0xcf, 0x77, 0xbe, 0xff, 0x1e, 0xef, 0xff, 0x07, 0xc3, 0xff, 0x8f, 0xff, 0xbf, 0xb8, 0xdc, 0xff, 0xdf, 0x77, 0xbe, 0xfe, 0x5e, 0xcf, 0xff, 0xdf, 0xc3, 0xff, 0x8f, 0xff, 0xbf, 0xb8, 0x5c, 0x8f, 0x9f, 0x07, 0xbe, 0xfe, 0xde, 0x1f, 0xff, 0xff, 0x81, 0xff, 0x8f, 0xff, 0xbf, 0xb9, 0x5c, 0x8f, 0x9f, 0x07, 0xbe, 0xfe, 0xde, 0x0f, 0xff, 0xff, 0x81, 0xff, 0x1f, 0xff, 0xbf, 0xb9, 0x5c, 0x8f, 0xbf, 0x27, 0xbe, 0xfe, 0xde, 0xcf, 0xff, 0xff, 0x81, 0xff, 0x1f, 0xff, 0xbf, 0xb9, 0x1c, 0xef, 0x3f, 0x77, 0xbe, 0xfe, 0x1e, 0xef, 0xff, 0xff, 0x99, 0xfe, 0x1f, 0xff, 0xbf, 0xb9, 0x1c, 0xef, 0x3f, 0x77, 0xbe, 0xfe, 0x0e, 0xef, 0xff, 0xff, 0x99, 0xfc, 0x3f, 0xff, 0xbf, 0xb9, 0x9e, 0xef, 0x7f, 0x77, 0xbe, 0xfc, 0xce, 0xef, 0xff, 0xff, 0x99, 0xf8, 0x3f, 0xff, 0xbf, 0xb9, 0x9e, 0x6e, 0x7f, 0x77, 0xbe, 0xfc, 0xee, 0xef, 0xff, 0xff, 0x98, 0xf0, 0x3f, 0xff, 0x83, 0xb9, 0x9e, 0x0e, 0x07, 0x77, 0xbe, 0x0c, 0xee, 0x0f, 0xff, 0xff, 0x98, 0x00, 0x7f, 0xff, 0x83, 0xb9, 0x9f, 0x0e, 0x07, 0x77, 0xbe, 0x0d, 0xee, 0x0f, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xbf, 0x6f, 0xff, 0xff, 0x5f, 0xff, 0x7f, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc2, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; void setup() { Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC); //oled显示logo display.drawBitmap(0,0,pic,128,64,1);// display.display(); display.clearDisplay(); delay(3000); Serial.print("Initializing SD card..."); //sd卡启动 if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } Serial.println("card initialized."); } uint32_t fileNum = 0; int i = 0; char filen[8] = {0}; void loop() { //循环读取sd卡上的图片,并显示到oled for(fileNum=0; fileNum<=5355;fileNum++) { //0000-5355.bmp 图片名字 //3帧跳过一帧 if(fileNum % 3 == 0){ continue; } sprintf(filen, "%04d.bmp", fileNum); File dataFile = SD.open(filen); if (dataFile) { //读取图片,并把图片的数据存放到buff中 dataFile.read(buff,BUFF_SIZE); dataFile.close(); display.clearDisplay(); //62个字节是图片文件中的头信息,62之后的是真实图片数据 //data: 40+14+4*2 -> end display.drawBitmap(0,0,buff+62,128,64,1);// display.display(); } // 图片打开失败 else { Serial.println("error opening file"); } } } 代码注释写的很清楚,就不再详细解释了。最后我们下载到零知标准板上,可以看看播放的效果: 更多详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 回复了主题帖: 【零知ESP8266】教程:手机APP控制RGB LED

    btty038 发表于 2019-6-21 16:16 不错不错  很好玩的样子
    那就动手试试吧~

  • 2019-06-21
  • 发表了主题帖: 【零知ESP8266】教程:手机APP控制RGB LED

    本次使用blynk app+服务器(本地) + 零知ESP8266开发板的组合方法,通过手机APP来控制RGB LED显示各种颜色。 1、硬件准备 (1)零知ESP8266开发板 (2)RGB LED (3)杜邦线若干 2、电路连接 接线很简单,对应R-D5,G-D6,B-D7,和blynk app里面控件的引脚设置是对应的: 3、手机APP 关于手机APP与blynk详细说明请参考:http://www.lingzhilab.com/bbs/index/showonepostz?pid=356 4、软件 (1)手机端 使用blynk新建工程,并选择设备NodeMCU或ESP8266,然后增加ZERGBA控件,如下: (2)ESP8266端如下: /* Comment this out to disable prints and save space */ #define BLYNK_PRINT Serial #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "xx"; // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "xx"; char pass[] = "xx"; char local_domain[] = "192.168.0.111"; void setup() { // Debug console Serial.begin(9600); Blynk.begin(auth, ssid, pass, local_domain,8080); } void loop() { Blynk.run(); } 上述代码只需要填写自己的TOKEN和wifi热点名字、密码即可。 5、测试验证 (1)在零知开发工具中,打开串口调试窗口看到如下信息: 就表明我们与服务器通信成功。 (2)在手机blynk app上,点击运行按钮后,开始运行,然后就可以控制RGB LED显示各种颜色了: 更多详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-06-20
  • 发表了主题帖: 【零知ESP8266】HTTP WEB 服务器示例

    1、概述 HTTP web server作为ESP8266的一个常用功能,在这里使用零知开源平台进行该示例的演示。 2、软件和硬件 硬件使用零知-ESP8266; 软件使用零知开发工具,自带示例: 3、方法步骤 (1)先在零知开发工具中打开AdvancedWebServer示例,或者复制下面的代码到零知开发工具中: /********************************************************** * 文件: x.ino by 零知实验室 * -^^- 零知开源,让电子制作变得更简单! -^^- * 时间: 2019/05/28 12:22 * 说明: ************************************************************/ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #ifndef STASSID #define STASSID "ssid" #define STAPSK "passwd" #endif const char *ssid = STASSID; const char *password = STAPSK; ESP8266WebServer server(80); const int led = 13; void handleRoot() { digitalWrite(led, 1); char temp[400]; int sec = millis() / 1000; int min = sec / 60; int hr = min / 60; snprintf(temp, 400, "<html>\ <head>\ <meta http-equiv='refresh' content='5'/>\ <title>ESP8266 Demo</title>\ <style>\ body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\ </style>\ </head>\ <body>\ <h1>Hello from ESP8266!</h1>\ <p>Uptime: %02d:%02d:%02d</p>\ <img src=\"/test.svg\" />\ </body>\ </html>", hr, min % 60, sec % 60 ); server.send(200, "text/html", temp); digitalWrite(led, 0); } void handleNotFound() { digitalWrite(led, 1); String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } server.send(404, "text/plain", message); digitalWrite(led, 0); } void setup(void) { pinMode(led, OUTPUT); digitalWrite(led, 0); Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); } server.on("/", handleRoot); server.on("/test.svg", drawGraph); server.on("/inline", []() { server.send(200, "text/plain", "this works as well"); }); server.onNotFound(handleNotFound); server.begin(); Serial.println("HTTP server started"); } void loop(void) { server.handleClient(); MDNS.update(); } void drawGraph() { String out = ""; char temp[100]; out += "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"400\" height=\"150\">\n"; out += "<rect width=\"400\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"1\" stroke=\"rgb(0, 0, 0)\" />\n"; out += "<g stroke=\"black\">\n"; int y = rand() % 130; for (int x = 10; x < 390; x += 10) { int y2 = rand() % 130; sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"1\" />\n", x, 140 - y, x + 10, 140 - y2); out += temp; y = y2; } out += "</g>\n</svg>\n"; server.send(200, "image/svg+xml", out); } (2)验证上述代码并上传到零知-ESP8266开发板; (3)我们打开零知开发工具的串口调试窗口,可以看到如下信息: (4)现在我们用ping工具测试下网络,得到如下信息: (5)上述步骤成功后,我们现在打开浏览器,打开网址:http://esp8266.local,可以看到如下信息: 更多详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 回复了主题帖: 贪吃蛇 for esp32(是时候表演真正的技术了)

    好奇

  • 2019-06-19
  • 发表了主题帖: 【零知ESP8266】教程:MESH 组网示例

    1、概述 MESH组网技术在IOT领域具有非常大的作用,应用非常广泛,主流的无线技术从最开始的Zigbee,到蓝牙,到这里的WIFI都实现了MESH组网技术。在这里使用零知开源平台演示WIFI WESH组网的使用。 2、软件和硬件 硬件使用零知-ESP8266开发板; 软件使用零知开发工具,自带示例: 3、方法步骤 (1)先在零知开发工具中打开HelloMesh示例,或者复制下面的代码到零知开发工具中: /********************************************************** * 文件: x.ino by 零知实验室 * -^^- 零知开源,让电子制作变得更简单! -^^- * 时间: 2019/05/28 12:22 * 说明: ************************************************************/ #include <ESP8266WiFi.h> #include <ESP8266WiFiMesh.h> #include <TypeConversionFunctions.h> #include <assert.h> const char exampleMeshName[] PROGMEM = "MeshNode_"; const char exampleWiFiPassword[] PROGMEM = "123456789";//ChangeThisWiFiPassword_TODO unsigned int requestNumber = 0; unsigned int responseNumber = 0; String manageRequest(const String &request, ESP8266WiFiMesh &meshInstance); transmission_status_t manageResponse(const String &response, ESP8266WiFiMesh &meshInstance); void networkFilter(int numberOfNetworks, ESP8266WiFiMesh &meshInstance); /* Create the mesh node object */ ESP8266WiFiMesh meshNode = ESP8266WiFiMesh(manageRequest, manageResponse, networkFilter, FPSTR(exampleWiFiPassword), FPSTR(exampleMeshName), "", true); /** Callback for when other nodes send you a request @param request The request string received from another node in the mesh @param meshInstance The ESP8266WiFiMesh instance that called the function. @returns The string to send back to the other node */ String manageRequest(const String &request, ESP8266WiFiMesh &meshInstance) { // We do not store strings in flash (via F()) in this function. // The reason is that the other node will be waiting for our response, // so keeping the strings in RAM will give a (small) improvement in response time. // Of course, it is advised to adjust this approach based on RAM requirements. /* Print out received message */ Serial.print("Request received: "); Serial.println(request); /* return a string to send back */ return ("Hello world response #" + String(responseNumber++) + " from " + meshInstance.getMeshName() + meshInstance.getNodeID() + "."); } /** Callback for when you get a response from other nodes @param response The response string received from another node in the mesh @param meshInstance The ESP8266WiFiMesh instance that called the function. @returns The status code resulting from the response, as an int */ transmission_status_t manageResponse(const String &response, ESP8266WiFiMesh &meshInstance) { transmission_status_t statusCode = TS_TRANSMISSION_COMPLETE; /* Print out received message */ Serial.print(F("Request sent: ")); Serial.println(meshInstance.getMessage()); Serial.print(F("Response received: ")); Serial.println(response); // Our last request got a response, so time to create a new request. meshInstance.setMessage(String(F("Hello world request #")) + String(++requestNumber) + String(F(" from ")) + meshInstance.getMeshName() + meshInstance.getNodeID() + String(F("."))); // (void)meshInstance; // This is useful to remove a "unused parameter" compiler warning. Does nothing else. return statusCode; } /** Callback used to decide which networks to connect to once a WiFi scan has been completed. @param numberOfNetworks The number of networks found in the WiFi scan. @param meshInstance The ESP8266WiFiMesh instance that called the function. */ void networkFilter(int numberOfNetworks, ESP8266WiFiMesh &meshInstance) { for (int networkIndex = 0; networkIndex < numberOfNetworks; ++networkIndex) { String currentSSID = WiFi.SSID(networkIndex); int meshNameIndex = currentSSID.indexOf(meshInstance.getMeshName()); /* Connect to any _suitable_ APs which contain meshInstance.getMeshName() */ if (meshNameIndex >= 0) { uint64_t targetNodeID = stringToUint64(currentSSID.substring(meshNameIndex + meshInstance.getMeshName().length())); if (targetNodeID < stringToUint64(meshInstance.getNodeID())) { ESP8266WiFiMesh::connectionQueue.push_back(NetworkInfo(networkIndex)); } } } } void setup() { // Prevents the flash memory from being worn out, see: https://github.com/esp8266/Arduino/issues/1054 . // This will however delay node WiFi start-up by about 700 ms. The delay is 900 ms if we otherwise would have stored the WiFi network we want to connect to. WiFi.persistent(false); Serial.begin(115200); delay(50); // Wait for Serial. //yield(); // Use this if you don't want to wait for Serial. // The WiFi.disconnect() ensures that the WiFi is working correctly. If this is not done before receiving WiFi connections, // those WiFi connections will take a long time to make or sometimes will not work at all. WiFi.disconnect(); Serial.println(); Serial.println(); Serial.println(F("Note that this library can use static IP:s for the nodes to speed up connection times.\n" "Use the setStaticIP method as shown in this example to enable this.\n" "Ensure that nodes connecting to the same AP have distinct static IP:s.\n" "Also, remember to change the default mesh network password!\n\n")); Serial.println(F("Setting up mesh node...")); /* Initialise the mesh node */ meshNode.begin(); meshNode.activateAP(); // Each AP requires a separate server port. // meshNode.setStaticIP(IPAddress(192, 168, 4, 22)); // Activate static IP mode to speed up connection times. } int32_t timeOfLastScan = -10000; void loop() { if (millis() - timeOfLastScan > 3000 // Give other nodes some time to connect between data transfers. || (WiFi.status() != WL_CONNECTED && millis() - timeOfLastScan > 2000)) { // Scan for networks with two second intervals when not already connected. String request = String(F("Hello world request #")) + String(requestNumber) + String(F(" from ")) + meshNode.getMeshName() + meshNode.getNodeID() + String(F(".")); meshNode.attemptTransmission(request, false); timeOfLastScan = millis(); // One way to check how attemptTransmission worked out if (ESP8266WiFiMesh::latestTransmissionSuccessful()) { Serial.println(F("Transmission successful.")); } // Another way to check how attemptTransmission worked out if (ESP8266WiFiMesh::latestTransmissionOutcomes.empty()) { Serial.println(F("No mesh AP found.")); } else { for (TransmissionResult &transmissionResult : ESP8266WiFiMesh::latestTransmissionOutcomes) { if (transmissionResult.transmissionStatus == TS_TRANSMISSION_FAILED) { Serial.println(String(F("Transmission failed to mesh AP ")) + transmissionResult.SSID); } else if (transmissionResult.transmissionStatus == TS_CONNECTION_FAILED) { Serial.println(String(F("Connection failed to mesh AP ")) + transmissionResult.SSID); } else if (transmissionResult.transmissionStatus == TS_TRANSMISSION_COMPLETE) { // No need to do anything, transmission was successful. } else { Serial.println(String(F("Invalid transmission status for ")) + transmissionResult.SSID + String(F("!"))); assert(F("Invalid transmission status returned from responseHandler!") && false); } } } Serial.println(); } else { /* Accept any incoming connections */ meshNode.acceptRequest(); } } (2)验证并上传上述代码到零知-ESP8266开发板; (3)测试:分别把上述代码上传到两个零知-ESP8266开发板,然后分别连接两个板子的串口调试窗口,然后就可以看到两个节点数据传输信息了: 更多详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 发表了主题帖: 【零知ESP8266】教程:OLED天气时钟

    本文演示通过OLED显示时钟和天气情况,主要利用的是openweathermap的免费天气API。 1、硬件准备 (1)零知ESP8266开发板 (2)OLED SSD1306模块 (3)若干杜邦线 2、电路连接 接线很简单,I2C接口对应连接即可: 接好后实物图如下: 2、软件代码 使用零知开发工具,使用了OLED和WeatherStation相关的软件库,因此需要安装对应的库: 安装完成后,我们新建工程: /* 2019年6月13日13:47:26 by 零知实验室 */ #include <ESPWiFi.h> #include <ESPHTTPClient.h> #include <JsonListener.h> // time #include <time.h> // time() ctime() #include <sys/time.h> // struct timeval #include <coredecls.h> // settimeofday_cb() #include "SSD1306Wire.h" #include "OLEDDisplayUi.h" #include "Wire.h" #include "OpenWeatherMapCurrent.h" #include "OpenWeatherMapForecast.h" #include "WeatherStationFonts.h" #include "WeatherStationImages.h" /*************************** * Begin Settings **************************/ // WIFI const char* WIFI_SSID = "xx"; const char* WIFI_PWD = "xx"; #define TZ 8 // (utc+) TZ in hours #define DST_MN 60 // use 60mn for summer time in some countries // Setup const int UPDATE_INTERVAL_SECS = 20 * 60; // Update every 20 minutes // Display Settings const int I2C_DISPLAY_ADDRESS = 0x3c; const int SDA_PIN = D3; const int SDC_PIN = D4; // OpenWeatherMap Settings // Sign up here to get an API key: // https://docs.thingpulse.com/how-tos/openweathermap-key/ String OPEN_WEATHER_MAP_APP_ID = "xxx"; //你的API KEY /* Go to https://openweathermap.org/find?q= and search for a location. Go through the result set and select the entry closest to the actual location you want to display data for. It'll be a URL like https://openweathermap.org/city/2657896. The number at the end is what you assign to the constant below. */ String OPEN_WEATHER_MAP_LOCATION_ID = "1795565"; //city:深圳 // Pick a language code from this list: // Arabic - ar, Bulgarian - bg, Catalan - ca, Czech - cz, German - de, Greek - el, // English - en, Persian (Farsi) - fa, Finnish - fi, French - fr, Galician - gl, // Croatian - hr, Hungarian - hu, Italian - it, Japanese - ja, Korean - kr, // Latvian - la, Lithuanian - lt, Macedonian - mk, Dutch - nl, Polish - pl, // Portuguese - pt, Romanian - ro, Russian - ru, Swedish - se, Slovak - sk, // Slovenian - sl, Spanish - es, Turkish - tr, Ukrainian - ua, Vietnamese - vi, // Chinese Simplified - zh_cn, Chinese Traditional - zh_tw. String OPEN_WEATHER_MAP_LANGUAGE = "zh_cn"; const uint8_t MAX_FORECASTS = 4; const boolean IS_METRIC = true; // Adjust according to your language const String WDAY_NAMES[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; const String MONTH_NAMES[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; /*************************** * End Settings **************************/ // Initialize the oled display for address 0x3c // sda-pin=14 and sdc-pin=12 SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); OLEDDisplayUi ui( &display ); OpenWeatherMapCurrentData currentWeather; OpenWeatherMapCurrent currentWeatherClient; OpenWeatherMapForecastData forecasts[MAX_FORECASTS]; OpenWeatherMapForecast forecastClient; #define TZ_MN ((TZ)*60) #define TZ_SEC ((TZ)*3600) #define DST_SEC ((DST_MN)*60) time_t now; // flag changed in the ticker function every 10 minutes bool readyForWeatherUpdate = false; String lastUpdate = "--"; long timeSinceLastWUpdate = 0; //declaring prototypes void drawProgress(OLEDDisplay *display, int percentage, String label); void updateData(OLEDDisplay *display); void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex); void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state); void setReadyForWeatherUpdate(); // Add frames // this array keeps function pointers to all frames // frames are the single views that slide from right to left FrameCallback frames[] = { drawDateTime, drawCurrentWeather, drawForecast }; int numberOfFrames = 3; OverlayCallback overlays[] = { drawHeaderOverlay }; int numberOfOverlays = 1; void setup() { Serial.begin(115200); Serial.println(); Serial.println(); // initialize dispaly display.init(); display.clear(); display.display(); //display.flipScreenVertically(); display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_CENTER); display.setContrast(255); WiFi.begin(WIFI_SSID, WIFI_PWD); int counter = 0; while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); display.clear(); display.drawString(64, 10, "Connecting to WiFi"); display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole); display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole); display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole); display.display(); counter++; } // Get time from network time service configTime(TZ_SEC, DST_SEC, "pool.ntp.org"); ui.setTargetFPS(30); ui.setActiveSymbol(activeSymbole); ui.setInactiveSymbol(inactiveSymbole); // You can change this to // TOP, LEFT, BOTTOM, RIGHT ui.setIndicatorPosition(BOTTOM); // Defines where the first frame is located in the bar. ui.setIndicatorDirection(LEFT_RIGHT); // You can change the transition that is used // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN ui.setFrameAnimation(SLIDE_LEFT); ui.setFrames(frames, numberOfFrames); ui.setOverlays(overlays, numberOfOverlays); // Inital UI takes care of initalising the display too. ui.init(); Serial.println(""); updateData(&display); } void loop() { if (millis() - timeSinceLastWUpdate > (1000L*UPDATE_INTERVAL_SECS)) { setReadyForWeatherUpdate(); timeSinceLastWUpdate = millis(); } if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) { updateData(&display); } int remainingTimeBudget = ui.update(); if (remainingTimeBudget > 0) { // You can do some work here // Don't do stuff if you are below your // time budget. delay(remainingTimeBudget); } } void drawProgress(OLEDDisplay *display, int percentage, String label) { display->clear(); display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(ArialMT_Plain_10); display->drawString(64, 10, label); display->drawProgressBar(2, 28, 124, 10, percentage); display->display(); } void updateData(OLEDDisplay *display) { drawProgress(display, 10, "Updating time..."); drawProgress(display, 30, "Updating weather..."); currentWeatherClient.setMetric(IS_METRIC); currentWeatherClient.setLanguage(OPEN_WEATHER_MAP_LANGUAGE); currentWeatherClient.updateCurrentById(¤tWeather, OPEN_WEATHER_MAP_APP_ID, OPEN_WEATHER_MAP_LOCATION_ID); drawProgress(display, 50, "Updating forecasts..."); forecastClient.setMetric(IS_METRIC); forecastClient.setLanguage(OPEN_WEATHER_MAP_LANGUAGE); uint8_t allowedHours[] = {12}; forecastClient.setAllowedHours(allowedHours, sizeof(allowedHours)); forecastClient.updateForecastsById(forecasts, OPEN_WEATHER_MAP_APP_ID, OPEN_WEATHER_MAP_LOCATION_ID, MAX_FORECASTS); readyForWeatherUpdate = false; drawProgress(display, 100, "Done..."); delay(1000); } void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { now = time(nullptr); struct tm* timeInfo; timeInfo = localtime(&now); char buff[16]; display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(ArialMT_Plain_10); String date = WDAY_NAMES[timeInfo->tm_wday]; sprintf_P(buff, PSTR("%s, %02d/%02d/%04d"), WDAY_NAMES[timeInfo->tm_wday].c_str(), timeInfo->tm_mday, timeInfo->tm_mon+1, timeInfo->tm_year + 1900); display->drawString(64 + x, 5 + y, String(buff)); display->setFont(ArialMT_Plain_24); sprintf_P(buff, PSTR("%02d:%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec); display->drawString(64 + x, 15 + y, String(buff)); display->setTextAlignment(TEXT_ALIGN_LEFT); } void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { display->setFont(ArialMT_Plain_10); display->setTextAlignment(TEXT_ALIGN_CENTER); display->drawString(64 + x, 38 + y, currentWeather.description); display->setFont(ArialMT_Plain_24); display->setTextAlignment(TEXT_ALIGN_LEFT); String temp = String(currentWeather.temp, 1) + (IS_METRIC ? "°C" : "°F"); display->drawString(60 + x, 5 + y, temp); display->setFont(Meteocons_Plain_36); display->setTextAlignment(TEXT_ALIGN_CENTER); display->drawString(32 + x, 0 + y, currentWeather.iconMeteoCon); } void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { drawForecastDetails(display, x, y, 0); drawForecastDetails(display, x + 44, y, 1); drawForecastDetails(display, x + 88, y, 2); } void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex) { time_t observationTimestamp = forecasts[dayIndex].observationTime; struct tm* timeInfo; timeInfo = localtime(&observationTimestamp); display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(ArialMT_Plain_10); display->drawString(x + 20, y, WDAY_NAMES[timeInfo->tm_wday]); display->setFont(Meteocons_Plain_21); display->drawString(x + 20, y + 12, forecasts[dayIndex].iconMeteoCon); String temp = String(forecasts[dayIndex].temp, 0) + (IS_METRIC ? "°C" : "°F"); display->setFont(ArialMT_Plain_10); display->drawString(x + 20, y + 34, temp); display->setTextAlignment(TEXT_ALIGN_LEFT); } void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { now = time(nullptr); struct tm* timeInfo; timeInfo = localtime(&now); char buff[14]; sprintf_P(buff, PSTR("%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min); display->setColor(WHITE); display->setFont(ArialMT_Plain_10); display->setTextAlignment(TEXT_ALIGN_LEFT); display->drawString(0, 54, String(buff)); display->setTextAlignment(TEXT_ALIGN_RIGHT); String temp = String(currentWeather.temp, 1) + (IS_METRIC ? "°C" : "°F"); display->drawString(128, 54, temp); display->drawHorizontalLine(0, 52, 128); } void setReadyForWeatherUpdate() { Serial.println("Setting readyForUpdate to true"); readyForWeatherUpdate = true; } 注意代码里面填写自己的APIkey和要查询的城市名称,这里填写的是深圳-shenzhen。 3、验证测试 将代码验证并上传到零知-ESP8266上面,打开串口调试工具,可以看到如下结果: 获取返回结果代码为:200,即表示成功了;如果是错误码,可以把地址粘贴到浏览器里看看是什么原因。 成功后OLED就会显示时钟和天气情况: 更多详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处  

  • 回复了主题帖: oled拼接 for esp32(是时候表演真正的技术了2)

    回复看看

  • 2019-06-13
  • 发表了主题帖: 零知ESP8266 Blynk手机APP教程:监控室内温湿度

    本次将使用blynk app+服务器(本地) + 零知ESP8266开发板的组合方式,通过手机APP来观察由ESP8266获取的温湿度情况。 1、准备 (1)零知ESP8266开发板 (2)SHT30温湿度模块 (3)零知开源开发工具 2、电路连接 线路连接很简单,按下图连接即可:   实物连接: 3、手机APP端 设置手机端Blynk可参考:http://www.lingzhilab.com/bbs/index/showonepostz?pid=356 我们需要两个组件分别显示温度和湿度信息,做好后界面如下: 页面组件可扫描下方二维码复制我共享的demo: 4、ESP8266端 核心代码如下: /* Comment this out to disable prints and save space */ #define BLYNK_PRINT Serial #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "xx"; // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "xx"; char pass[] = "xx"; char local_domain[] = "192.168.0.111"; /*SHT3X 传感器 * 使用软I2C接口 */ #define SHT3X_SDA D5 #define SHT3X_SCL D6 #include "SHT3X.h" SlowSoftWire shtWire(SHT3X_SDA,SHT3X_SCL,true); HTU3X myHumidity; BlynkTimer timer; void myTimerEvent() { float humd, temp; myHumidity.readTempAndHumi(&temp, &humd); Serial.print("时间:"); Serial.print(millis()); Serial.print(" 温度:"); Serial.print(temp, 1); Serial.print(" °C"); Serial.print(" 湿度:"); Serial.print(humd, 1); Serial.print("%"); Serial.println(); Blynk.virtualWrite(V0, temp); Blynk.virtualWrite(V1, humd); } void setup() { // Debug console Serial.begin(9600); Blynk.begin(auth, ssid, pass, local_domain,8080); myHumidity.begin(shtWire); timer.setInterval(1000L, myTimerEvent); } void loop() { Blynk.run(); timer.run(); // Initiates BlynkTimer } 更改代码中的IP、token等信息,然后把代码验证并上传到零知-ESP8266开发板板上即可。 5、验证测试 在手机blynk app上可以观察到如下结果: 可以很直观的看到温湿度的曲线分布,可用于实时监测。 更多详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 发表了主题帖: 零知ESP8266教程:SmartConfig一键配网

    这次了解SmartConfig与Airkiss一键配网,给ESP8266一键配网上云端。  一般WiFi模块如果要连接上网络,都需要将SSID名称、密码设置到模块当中。 一般有几种方式: 一种是通过串口接到输入设备,通过串口输入AT指令(SSID名称和密码); 另一种是设备提供一个AP热点,手机连上这个热点,然后通过手机把家里的WiFi的SSID和密码配置到设备上,最后手机再切换回家里的WiFi ; 还有另外一种就是SmartConfig技术配置,微信的AirKiss、ESP8266的esptouch,这是最智能的配网方式。 接下来我们通过实例来做一个小demo: 1、准备 (1)零知ESP8266开发板 (2)零知开源开发工具   测试demo: #include <ESP8266WiFi.h> /** * by 零知实验室 * -- 零知开源,让电子制作变得更简单! -- * 作者:云上上云 * 说明: 一键配网 **/ void smartConfig() { WiFi.mode(WIFI_STA); Serial.println("\r\nWait for Smartconfig等待连接"); delay(2000); // 等待配网 WiFi.beginSmartConfig(); while (1) { Serial.print("."); delay(500); if (WiFi.smartConfigDone()) { Serial.println("SmartConfig Success"); Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str()); Serial.printf("PSW:%s\r\n", WiFi.psk().c_str()); WiFi.setAutoConnect(true); // 设置自动连接 break; } } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void setup() { Serial.begin(115200); smartConfig(); } void loop() { delay(100); Serial.println("配置成功"); } 2、输入上述测试demo,验证代码,选择ESP8266,上传代码,打开调试窗口,串口选择1152000,窗口会不断打印一个一个的点,等待连接。 3、使用ESP8266提供的App ESPTouch 或者 SmartConfigAPP,进行如下操作: (1)打开APP (2)设置SmartConfig (3)配置 4、当手机端配置成功,会出现如下结果: 显示配置成功即操作成功了,去动手试试吧~~   此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-06-11
  • 发表了主题帖: 零知ESP8266 SSD1306 OLED教程:绘制二维码

    二维码现在随处可见,这次就教大家如何使用零知ESP8266开发板在SSD1306 OLED显示屏上绘制QR码。 1、硬件准备 (1)零知ESP8266开发板 (2)SSD1306 OLED模块 (3)杜邦线若干 2、软件准备 本次使用了OLED相关的软件库,因此需要安装相关的软件库: 安装好库,在零知开发工具中就可以看到QRCode二维码相关例子,打开它: 核心代码如下,非常简单: /* ********************************************************************************* * ESP8266 QRcode * dependency library : * ESP8266 Oled Driver for SSD1306 display by Daniel Eichborn, Fabrice Weinberg * 零知ESP8266-OLED * SDA --> D1-sda * SCL --> D0-scl ***********************************************************************************/ #include <qrcode.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); QRcode qrcode (&display); void setup() { Serial.begin(115200); Serial.println(""); Serial.println("Starting..."); display.begin(SSD1306_SWITCHCAPVCC, 0x3c); display.clearDisplay(); // enable debug qrcode qrcode.debug(); // Initialize QRcode display using library qrcode.init(); // create qrcode qrcode.create("www.lingzhilab.com"); } void loop() { } 3、电路连接 接线很简单,I2C接口对应连接即可: 接好后实物图如下: 现在验证代码然后上传到零知-esp8266,可以看到如下结果啦: 用手机QQ扫一扫看看: 更多详细资料可到零知实验室官网免费获取。         此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 发表了主题帖: ESP8266 零知教程:WiFiScan库的使用

    本帖最后由 roc2 于 2019-6-11 10:42 编辑 概述: 无线网络提供的WiFi热点,大部分都开放了SSID广播(WiFi热点也可以隐藏的),Scan WiFi的功能就是扫描出所有附近的WiFi热点的SSID信息,这样一来,客户端就可以根据需要选择不同的SSID连入对应的无线网络中。 Scan WiFi库提供了两种方式实现扫描过程: 同步扫描:通过单个函数在一次运行中完成,需要等待完成所有操作才能继续运行下面的操作。 异步扫描:把上面的过程分成几个步骤,每个步骤由一个单独函数完成,我们可以在扫描过程中执行其他任务。 ESP8266WiFiScan库 ESP8266WiFiScan库,大家使用的时候只需要引入: #include<ESP8266WiFi.h> ") rgba(220, 220, 220, 0.5); display:block; left:0px; top:-15px"> 扫描操作方法 1.scanNetworks —— 同步扫描周边有效wifi网络 函数说明: /** * Start scan WiFi networks available * @param async run in async mode(是否启动异步扫描) * @param show_hidden show hidden networks(是否扫描隐藏网络) * @param channel scan only this channel (0 for all channels)(是否扫描特定通道) * @param ssid* scan for only this ssid (NULL for all ssid's)(是否扫描特定的SSID) * @return Number of discovered networks */int8_t scanNetworks(bool async = false, bool show_hidden = false, uint8 channel = 0, uint8* ssid = NULL); 2.scanNetworks(async ) —— 异步扫描周边有效wifi网络 函数说明: /** * Start scan WiFi networks available * @param async run in async mode(是否启动异步扫描) * @param show_hidden show hidden networks(是否扫描隐藏网络) * @param channel scan only this channel (0 for all channels)(是否扫描特定通道) * @param ssid* scan for only this ssid (NULL for all ssid's)(是否扫描特定的SSID) * @return Number of discovered networks */int8_t scanNetworks(bool async = false, bool show_hidden = false, uint8 channel = 0, uint8* ssid = NULL); 3.scanNetworksAsync —— 异步扫描周边wifi网络,并回调结果 函数说明: /** * Starts scanning WiFi networks available in async mode * @param onComplete the event handler executed when the scan is done * @param show_hidden show hidden networks */void scanNetworksAsync(std::function<void(int)> onComplete, bool show_hidden = false); 4. scanComplete —— 检测异步扫描的结果 函数说明: /** * called to get the scan state in Async mode(异步扫描的结果函数) * @return scan result or status * -1 if scan not find * -2 if scan not triggered */ int8_t scanComplete(); 5.scanDelete —— 从内存中删掉最近扫描结果 函数说明: /** * delete last scan result from RAM(从内存中删除最近的扫描结果) */void scanDelete(); 扫描结果方法 1. SSID —— 获取wifi网络名字 函数说明: /** * Return the SSID discovered during the network scan. * @param i specify from which network item want to get the information * @return ssid string of the specified item on the networks scanned list */String SSID(uint8_t networkItem);   2.RSSI —— 获取wifi网络信号强度 函数说明: /** * Return the RSSI of the networks discovered during the scanNetworks(信号强度) * @param i specify from which network item want to get the information * @return signed value of RSSI of the specified item on the networks scanned list */int32_t RSSI(uint8_t networkItem); 3. encryptionType —— 获取wifi网络加密方式 函数说明: /** * Return the encryption type of the networks discovered during the scanNetworks(加密方式) * @param i specify from which network item want to get the information * @return encryption type (enum wl_enc_type) of the specified item on the networks scanned list * ............ Values map to 802.11 encryption suites..................... * AUTH_OPEN ----> ENC_TYPE_WEP = 5, * AUTH_WEP ----> ENC_TYPE_TKIP = 2, * AUTH_WPA_PSK ----> ENC_TYPE_CCMP = 4, * ........... except these two, 7 and 8 are reserved in 802.11-2007....... * AUTH_WPA2_PSK ----> ENC_TYPE_NONE = 7, * AUTH_WPA_WPA2_PSK ----> ENC_TYPE_AUTO = 8 */uint8_t encryptionType(uint8_t networkItem); 4. BSSID —— 获取wifi网络mac地址 函数说明: /** * return MAC / BSSID of scanned wifi (物理地址) * @param i specify from which network item want to get the information * @return uint8_t * MAC / BSSID of scanned wifi */uint8_t * BSSID(uint8_t networkItem); /** * return MAC / BSSID of scanned wifi (物理地址) * @param i specify from which network item want to get the information * @return uint8_t * MAC / BSSID of scanned wifi */String BSSIDstr(uint8_t networkItem); 5.getNetworkInfo —— 获取整体网络信息,名字,信号强度等 函数说明: /** * loads all infos from a scanned wifi in to the ptr parameters * @param networkItem uint8_t * @param ssid const char** * @param encryptionType uint8_t * * @param RSSI int32_t * * @param BSSID uint8_t ** * @param channel int32_t * * @param isHidden bool * * @return (true if ok) */ bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden); 6. channel —— 获取wifi网络通道号 函数说明: /** * return channel of scanned wifi(通道号) */int32_t channel(uint8_t networkItem); 7. isHidden —— 判断wifi网络是否是隐藏网络 函数说明: /** * return if the scanned wifi is Hidden (no SSID)(判断扫描到的wifi是否是隐藏wifi) * @param networkItem specify from which network item want to get the information * @return bool (true == hidden) */bool isHidden(uint8_t networkItem); 动手操作 多说不宜,实验是检验真理的唯一标准,下面我们就来实际操作一下吧。 打开零知开源开发工具,新建一个项目,输入以下代码,验证,上传。 测试demo: /** * Demo: * STA模式下,演示同步扫描Scan wifi功能 * @author 云上上云 * @date 2019/06/01 */#include <ESP8266WiFi.h> //以下三个定义为调试定义#define DebugBegin(baud_rate) Serial.begin(baud_rate)#define DebugPrintln(message) Serial.println(message)#define DebugPrint(message) Serial.print(message) void setup() { //设置串口波特率,以便打印信息 DebugBegin(115200); //延时5s 为了演示效果 delay(5000); // 我不想别人连接我,只想做个站点 WiFi.mode(WIFI_STA); //断开连接 WiFi.disconnect(); delay(100); DebugPrintln("Setup done"); } void loop() { DebugPrintln("scan start"); // 同步扫描,等待返回结果 int n = WiFi.scanNetworks(); DebugPrintln("scan done"); if (n == 0){ DebugPrintln("no networks found"); }else{ DebugPrint(n); DebugPrintln(" networks found"); for (int i = 0; i < n; ++i){ DebugPrint(i + 1); DebugPrint(": "); //打印wifi账号 DebugPrint(WiFi.SSID(i)); DebugPrint(","); DebugPrint(String("Ch:")+WiFi.channel(i)); DebugPrint(","); DebugPrint(WiFi.isHidden(i)?"hide":"show"); DebugPrint(" ("); //打印wifi信号强度 DebugPrint(WiFi.RSSI(i)); DebugPrint("dBm"); DebugPrint(")"); //打印wifi加密方式 DebugPrintln((WiFi.encryptionType(i) == ENC_TYPE_NONE)?"open":"*"); delay(10); } } DebugPrintln(""); // 延时5s之后再次扫描 delay(5000); } 测试结果(附近潜在的WiFi热点):它可以扫描完附件所有WiFi。 更多详细资料可到零知实验室官网免费获取。       此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-06-05
  • 发表了主题帖: 零知开源分享-零知ESP8266开发板发布了

    本帖最后由 roc2 于 2019-6-5 11:19 编辑 零知实验室现在已发布零知-ESP8266开发板,该开发板主要面向无线控制应用场景,硬件不仅支持零知开源平台,同时可以兼容NodeMCU,利用这个产品大家将很容易的做无线控制相关的作品。 1、硬件特性 (1)采用ESP12F模块; (2)兼容NodeMCU; (3)支持一键下载; (4)板载LED与按键; (5)板载PCB天线。 2、开发板靓照 引脚分配图: 3、软件开发 (1)支持零知开源平台,配套大量教程和技术支持; (2)支持NodeMCU开发(LUA开发); (3)支持乐鑫SDK开发(需要一定的基础); (4)支持AT指令模式,方便接入到其他MCU。 配合零知开发工具快速开发 ,简单上手: 当前开发工具已经支持零知-标准板、增强板、迷你板、零知-ESP8266、ESP32 DEVKIT多种开发板。(当前已经开发到3.30版本,大家有好的建议我们也虚心采纳)。 现已配有大量资料和教程,让开发更简单: 为了感谢大家对零知开源平台的支持,本次在零知官网提供100个ESP8266开发板,只需要3元,有需要可到零知实验室官网进行购买。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-05-30
  • 发表了主题帖: 零知开源分享-移植 LittleVGL.GUI库demo演示

    Little VGL作为一个优秀、源码开源的GUI库,内存占用少但界面炫酷,目前得到越来越多的支持。零知开源平台已移植了该库,下面在零知开发板-增强板上进行实验演示。 特性:16, 32 or 64 bit microcontroller or processor16 MHz clock speed8 kB RAM for static data and >2 KB RAM for dynamic data (graphical objects)64 kB program memory (flash)支持GPU 1、硬件准备 (1)零知开发板-增强板 (2)TFT液晶显示屏 (3)零知开发工具 (4)杜邦线若干 2、硬件连接 使用2.4寸、ILI9341驱动、带触摸屏XPT2046的TFT液晶显示屏作为显示工具,与零知增强板配合使用,硬件连接按下表进行连线: 3、编写代码 因为使用了TFT液晶显示屏作为显示工具,所以需要用到FSMC_TFT库,同时也用到触摸屏功能,也需要XPT2046的软件库,相关的库文件可到零知实验室官网免费获取。 (1)显示设备 初始化: /** * Initialize your display here */ void tft_init(void) {         lv_disp_drv_t disp_drv;         lv_disp_drv_init(&disp_drv);                   disp_drv.disp_fill = tft_fill;         disp_drv.disp_map = tft_map;         disp_drv.disp_flush = tft_flush;                   lv_disp_drv_register(&disp_drv); }复制代码 液晶屏与LittleVGL库相关联,进行显示的操作: /** * Flush a color buffer * @param x1 left coordinate of the rectangle * @param x2 right coordinate of the rectangle * @param y1 top coordinate of the rectangle * @param y2 bottom coordinate of the rectangle * @param color_p pointer to an array of colors */ void tft_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p) {         //        LCD_Color_Fill(x1,y1,x2,y2,color_p);         u16 height,width;         u16 i,j;         width=x2-x1+1;                         //得到填充的宽度         height=y2-y1+1;                        //高度         for(i=0;ifull;//写入数据                         color_p++;                 }         }         lv_flush_ready(); } /** * Put a color map to a rectangular area * @param x1 left coordinate of the rectangle * @param x2 right coordinate of the rectangle * @param y1 top coordinate of the rectangle * @param y2 bottom coordinate of the rectangle * @param color_p pointer to an array of colors */ void tft_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p) {         u16 height,width;         u16 i,j;         width=x2-x1+1;                         //得到填充的宽度         height=y2-y1+1;                        //高度         for(i=0;ifull;//写入数据                         color_p++;                 }         } } /** * Fill a rectangular area with a color * @param x1 left coordinate of the rectangle * @param x2 right coordinate of the rectangle * @param y1 top coordinate of the rectangle * @param y2 bottom coordinate of the rectangle * @param color fill color */ void tft_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color) {         LCD_Fill(x1,y1,x2,y2,color.full); }复制代码 (2)输入设备,即用触摸屏作为输入设备 初始化: /** * init touchpad here */ /************************* * Input device interface *************************/ void touchpad_init(void) {                   lv_indev_drv_t indev_drv;                       /*Descriptor of an input device driver*/         lv_indev_drv_init(&indev_drv);                  /*Basic initialization*/         indev_drv.type = LV_INDEV_TYPE_POINTER;         /*The touchpad is pointer type device*/         indev_drv.read = ex_tp_read;                 /*Library ready your touchpad via this function*/         lv_indev_drv_register(&indev_drv);              /*Finally register the driver*/ }复制代码 触摸位置的读取: /* * touch read position */ bool ex_tp_read(lv_indev_data_t *data) {         bool tp_is_pressed = ts.touched(); /*TODO read here the state of toush pad*/         int16_t last_x = 0;         int16_t last_y = 0;                   if(tp_is_pressed) {                 /*Touch pad is being pressed now*/                 TS_Point p = ts.getPoint();                                   //convert to lcd position                 last_y = 320-(p.x *320)/4095;       /*TODO save the current X coordinate*/                 last_x = 240-(p.y *240)/4095;       /*TODO save the current Y coordinate*/                                   Serial.print("touched:");                 Serial.print(last_x);Serial.print(",");Serial.println(last_y);         }                   data->point.x = last_x;         data->point.y = last_y;         data->state = tp_is_pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;                   return false;       /*Return false because no moare to be read*/ }复制代码 注:触摸屏最好先进行校准,这样读取位置就比较精确,这里简单的进行了一下转换,对于尺寸较大的控件影响不大,如果是尺寸很小的控件不做校准,读取位置就会有很大的偏差。 (3)LVGL system tick 使用一个1ms定时器中断进行提供: void timer_handler(stimer_t *timer) {                 lv_tick_inc(1); } void lvgl_timer_init() {         static stimer_t m_timer;         m_timer.timer = TIM3;         TimerHandleInit(&m_timer, 10-1, 8400-1);//1ms timer         attachIntHandle(&m_timer, timer_handler); } 复制代码 (4)创建lvgl的一个demo 这里直接调用了官方示例的demo进行演示。 4、运行效果 还可以使用PC端模拟器辅助开发调试UI,以下是windows上Qt运行效果: 相关库文件和完整工程代码可到零知实验室官网免费获取。

  • 2019-05-29
  • 发表了主题帖: 零知开源分享 - 增强板FSMC接口TFT显示屏实验

    零知增强板与标准板相比,增强板增加了FSMC接口,该接口能很方便的连接TFT显示屏,进行LCD相关的显示操作,下面以ILI9341型号为例介绍在零知-增强板上的使用方法。1、硬件准备 (1)零知开发板-增强板 零知增强板采用Arduino mega2560相同的板框设计,同时引脚接口和mega2560完全兼容。零知增强板使用了STM32F407VET6 作为MCU,包含70个IO引脚、16路PWM、16路ADC(12位精度)、6个UART接口,还拥有FSMC、DCMI、I2S、CAN、Ethernet、SDIO、SWD、USB-OTG等专用外设接口,其中的DCMI接口单独引出可以直接接入OV2640/OV7670模块使用;板上的一个USB转串口设备接口可以配合零知开发工具实现一键下载,使用非常方便。 (2)TFT液晶显示屏 (3)杜邦线若干 2、电路连接 为了高速显示,我们使用LCD的16位模式,因此我们要把LCD模块在硬件上切换到16位模式(一般是通过短路或者断开一个焊点)。这里我们先使用杜邦线连接,后面会考虑做一个扩展板直接插入LCD模块以去除连线的麻烦,线路如下进行连接: 3、程序 确保连线正确即可上传程序验证可不可行。使用零知开发工具。 零知实验室官网提供完整的工程,可以免费获取。完整工程需放置到软件库目录的project目录下,然后在零知开发工具中打开,已经把接口进行了二次封装以便更易使用,在这个基础上再进行自己的开发将会非常容易。 核心代码如下: /********************************************************** *    文件: fsmc-ili9341.ino      by 零知实验室 *    -^^- 零知开源,让电子制作变得更简单! -^^- ************************************************************/ #include "fsmc_tft.h" //图片测试文件 #include "image_board.h" #include "img1.h" #include "img2.h" #include "img3.h" #include "img4.h" #include "img5.h" #include "img6.h" #include "img7.h" FSMC_TFT tft; // 复位或上电后运行一次: void setup() {     //在这里加入初始化相关代码,只运行一次:         Serial.begin(9600);         Serial.println("init lcd");         tft.begin();                   uint16_t lcd_id = tft.get_id();         Serial.print("init done, lcd id:0x");         Serial.println(lcd_id,HEX);                   /*********************************************************/                   //清屏         tft.clear(WHITE);                           //设置背景:WHITE, 绘图颜色:RED         tft.setColor(WHITE, RED);                   //显示字符串,x,y坐标,尺寸大小         tft.print(16,10,24, "www.lingzhilab.com");                   tft.setColor(WHITE, BLUE);         //显示自定义汉字,为减小代码体积,在tft_font中开启16号/24号字体,再然后这里就可以使用了,要与开启字号对应         tft.printCN(70,40,24,"零知开源");         tft.printCN(2,70,24,"让电子制作变得更简单");                   //图片表情         tft.showPicture(0,100,20,120,gImage_1);         tft.showPicture(30,100,50,120,gImage_2);         tft.showPicture(60,100,80,120,gImage_3);         tft.showPicture(90,100,110,120,gImage_4);         tft.showPicture(120,100,140,120,gImage_5);         tft.showPicture(150,100,170,120,gImage_6);         tft.showPicture(180,100,200,120,gImage_7);                   //图像尺寸要对应,否则容易图像混乱         tft.showPicture(0,140,237,320,gImage_pics);                   //绘制圆,坐标80,80,半径20         //tft.circle(80,80,20);                   //直线         //tft.line(80,100,90,200);                   //矩形         //tft.rectangle(120,100,140,200);                   //填充矩形         //tft.fill(150,100,170,200,RED);                   //数字,坐标20,130,打印的数字:1234, 数字位数:4, 尺寸:24         //tft.print(20,130,1234,4,24);                     } //一直循环执行: void loop() {     // 在这里加入主要程序代码,重复执行: }复制代码 4、显示效果 代码编写了显示中文、英文、表情、图片等功能,还提供了绘制直线、圆、矩形、填充矩形等功能,由于中文编码太大,这里为了演示用仅添加了要用的几个中文字,需要其他中文字可自行添加。 最终显示效果如下: 完整工程代码可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-05-27
  • 发表了主题帖: 零知开源分享 - HC-SR04超声波模块使用

    超声波测量距离简单实用,本次使用HC-SR04超声波模块与零知开发板进行讲解,学会使用可把模块应用于DIY小车的避开障碍物功能上。 1、硬件准备 (1)零知开发板-标准板 (2)HC-SR04超声波模块 如上图所示,VCC 供5V电源, GND 为地线,TRIG 触发控制信号输入,ECHO 回响信号输出等四个接口端。2、电路连接接线比较简单,按照如下顺序连线即可: 3、程序编写根据模块的原理来进行代码编写,超声测距时的操作时序如下:以上时序图表明你只需要提供一个 10uS 以上脉冲触发信号,该模块内部将发出 8 个 40kHz 周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。公式:uS/58=厘米或者 uS/148=英寸;或是:距离=高电平时间*声速(340M/S)/2;建议测量周期为 60ms 以上,以防止发射信号对回响信号的影响。注意:1、此模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则会影响模块的正常工作。2、测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果。编写代码如下:/** *    文件: 超声测距.ino      by 零知实验室 *    -^^- 零知开源,让电子制作变得更简单! -^^- **/ #define SR04_TRIG        9 #define SR04_ECHO        10 // the setup routine runs once when you press reset: void setup() {     // put your setup code here, to run once:                   pinMode(SR04_TRIG, OUTPUT);         pinMode(SR04_ECHO, INPUT);                   Serial.begin(9600); } // the loop routine runs over and over again forever: void loop() {     // put your main code here, to run repeatedly:                   int distance = getDistance();                   Serial.print("distance = ");         Serial.println(distance);                   delay(300); }复制代码 4、结果 使用零知开发工具上传程序,把程序上传到开发板后,可以测得如下所示距离数据: 完整代码工程可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-05-25
  • 发表了主题帖: 零知开源分享 - BMP180大气压传感器模块的使用

    BMP180作为一个高精度、超小体积的气压传感器,在很多应用场景下都能见到它的身影,比如航模等一些需要高度数据的场合。下面将把它应用于零知平台进行演示。 1、硬件、软件准备 (1)零知开发板-标准板http://c.51hei.com/d/forum/201905/25/162306zfeog6ifbbwvcf26.jpg 零知标准板使用了STM32F103RBT6 作为MCU,采用32位高性能ARM核心,;包含37个IO引脚、15路PWM、15路ADC(12位精度)、一个USB设备接口、一个USB转串口设备接口;可以使用USB、AC-DC适配器、LI-PO等多种方式供电;供电电压 7v-28v,范围非常的宽。同时零知标准板配合零知开发工具能实现一键下载,使用非常方便。 (2)BMP180大气压传感器模块 http://c.51hei.com/d/forum/201905/25/162336pmg0s2702uuzku7u.jpg 该模块VCC为5V,可使用3.3V和5V电压供电。 (3)   杜邦线若干 (4)零知开发工具 http://c.51hei.com/d/forum/201905/25/162435uso4b2sb40ni8kib.png 2、电路连接 这里使用3.3V供电,把SCL和SDA引脚分别接标准板的A5、A4引脚即可。如下: http://c.51hei.com/d/forum/201905/25/162503ia4xowcawea5vtxi.png 3、测试 根据芯片说明书,大气压力与海拔高度对应关系如下: http://c.51hei.com/d/forum/201905/25/162529imcbc2w8c28eednd.jpg 核心代码: /** *    文件: BMP180模块测试.ino      by 零知实验室 *    -^^- 零知开源,让电子制作变得更简单! -^^- **/ #include "BMP180.h" Adafruit_BMP085 bmp;     void setup() {   Serial.begin(9600);   if (!bmp.begin()) {         Serial.println("BMP180 传感器启动失败");         while (1) {}   } }     void loop() {     Serial.print("温度:");     Serial.print(bmp.readTemperature());     Serial.println(" ℃");           Serial.print("压力:");     Serial.print(bmp.readPressure());     Serial.println(" Pa");           // 标准气体时测量的数据 101325 Pa     Serial.print("高度:");     Serial.print(bmp.readAltitude());     Serial.println(" m");     Serial.print("海平面压力:");     Serial.print(bmp.readSealevelPressure());     Serial.println(" Pa");   // 根据当地的海平面压强进行更精确的实际高度计算     Serial.print("真实高度:");     Serial.print(bmp.readAltitude(101400));     Serial.println(" m");           Serial.println();     delay(500); }复制代码 上述代码测量真实高度时需根据当地的实际气压进行校正,在这里我使用中央气象台查询到的作为依据: http://c.51hei.com/d/forum/201905/25/162726dpsrer6m8k70qss8.jpg 注:1014hPa = 101400Pa,这里的气压值没有很精确,可能会有存在误差。 4、测试结果 查询当地的海拔高度为14米: http://c.51hei.com/d/forum/201905/25/162802wv767al7pjpin3g7.jpg 实际测量如下: http://c.51hei.com/d/forum/201905/25/162831kcqvcoq8cw0o8w2c.jpg 完整代码工程和更多的详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-05-24
  • 发表了主题帖: 零知开源分享 - MPU6050六轴数据输出

    MPU6050模块应用于零知平台,使用该模块测量三轴加速度和三轴陀螺仪数据。 硬件准备 (1)零知开发板-标准板 (2)MPU6050模块 (3)杜邦线若干 1、电路连接 模块的SCL和SDA分别与零知标准板的I2C接口连接即A5和A4脚,供电3.3V,其他脚默认。 2、程序烧录 打开零知开发工具,找到相应代码即可。 3、核心代码如下: /* I2C interface MPU6050 demo * powered by  零知实验室 */ #include "MPU6050.h" // 默认I2C地址为 0x68 // AD0 low = 0x68 // AD0 high = 0x69 MPU6050 accelgyro; int16_t ax, ay, az;//三轴加速度值 int16_t gx, gy, gz;//三轴陀螺仪值 float nax,nay,naz; float ngx,ngy,ngz;//转换后的实际值 #define LED_PIN LED_BUILTIN bool blinkState = false; void setup() {     Serial.begin(9600);     // MPU6050初始化设置     Serial.println("Initializing I2C devices...");     accelgyro.initialize();     // verify connection     Serial.println("Testing device connections...");         if(accelgyro.testConnection()){                 Serial.println("MPU6050 connection successful");         }else{                 Serial.println("MPU6050 connection failed");         }           //使用LED进行指示     pinMode(LED_PIN, OUTPUT);           //        accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_16);//加速度参数 //        accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_500);//陀螺仪 } void loop() {     // 获取原始的数值:三轴加速度值和三轴陀螺仪数值     accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);     // 分别获取     //accelgyro.getAcceleration(&ax, &ay, &az);     //accelgyro.getRotation(&gx, &gy, &gz);     // 显示打印     Serial.print(" acc:\t");     Serial.print(ax); Serial.print("\t");     Serial.print(ay); Serial.print("\t");     Serial.print(az); Serial.print("\t");         Serial.print("\t gyro:\t");     Serial.print(gx); Serial.print("\t");     Serial.print(gy); Serial.print("\t");     Serial.println(gz);                   //实际数值转换         accelgyro.readNormalizeAccel(&nax,&nay,&naz);         accelgyro.readNormalizeGyro(&ngx,&ngy,&ngz);         Serial.print("Normalize acc:\t");     Serial.print(nax); Serial.print("\t");     Serial.print(nay); Serial.print("\t");     Serial.print(naz); Serial.print("\t");         Serial.print("\t Normalize gyro:\t");     Serial.print(ngx); Serial.print("\t");     Serial.print(ngy); Serial.print("\t");     Serial.println(ngz);     // blink LED to indicate activity     blinkState = !blinkState;     digitalWrite(LED_PIN, blinkState);     delay(300); }复制代码 完整代码可到零知实验室官网免费获取,完整工程需放到lingzhi_library下的project文件夹下。 4、当我们读取到原始数值后需要转换才可得到实际的值,完整代码已经做了转换,结果如下: 更多详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-05-23
  • 发表了主题帖: 零知开源分享-ADXL345三轴传感器的使用

    本帖最后由 roc2 于 2019-5-23 15:41 编辑 本篇文章将使用三轴加速度传感器和零知开发板在零知平台上进行加速度和单双击检测功能演示。通过本文的介绍让大家学会如何使用这款功能强大的三轴加速度传感器。 1、说明 MCU:零知开发板-标准板 传感器:ADXL345三轴加速度传感器              ADXL345 是 ADI 公司推出的基于 iMEMS 技术的 3 轴、数字输出加速度传感器。它支持标准的 I2C 或 SPI 数字接口,自带 32 级 FIFO 存储,并且内部有多种运动状态检测和灵活的中断方式等特性。 2、电路连接 接线很简单,只需要把传感器模块的SCL、SDA引脚与零知标准板的I2C(A5、A4)引脚相连接即可,供电3.3V,其他引脚采用模块默认的连接。 连接好线路后,就可以上传代码了,使用零知开发工具,找到相应代码即可。开发工具可到零知实验室管前往免费获取。 核心代码如下: /* *        ADXL345 三轴加速度传感器DEMO *        powered by 零知实验室 */ #include "ADXL345.h" // 默认的I2C地址为0x53 ADXL345 accel; int16_t ax, ay, az;//原始值 float nx,ny,nz;//重力加速度 #define LED_PIN LED_BUILTIN bool blinkState = false; //检测单击、双击动作参数设置 void checkActivitySetup() {         accel.setTapAxisXEnabled(false);//设置X轴方向敲击检测         accel.setTapAxisYEnabled(false);//y轴方向检测         accel.setTapAxisZEnabled(true);                   accel.setTapThreshold(40);//界限设置:40*0.0625 = 2.5g         accel.setTapDuration(32);//持续时间:32*0.625ms = 20 ms         accel.setDoubleTapLatency(80);//延迟:80*1.25ms = 100ms         accel.setDoubleTapWindow(240);//窗口:240*1.25ms = 300ms        } void checkActivity() {         Activites act = accel.readActivites();   if (act.isDoubleTap)   {     Serial.println("Double Tap Detected");   } else if (act.isTap)   {     Serial.println("Tap Detected");   }else   {          Serial.println("no activity");   } } void setup() {           Serial.begin(9600);     // 初始化ADXL345     Serial.println("Initializing I2C devices...");     accel.initialize();     // 检测是否连接ADXL345     Serial.println("Testing device connections...");         if(accel.testConnection()){                 Serial.println("ADXL345 connection successful");         }else{                 Serial.println("ADXL345 connection failed");         }                    // Set measurement range   // +/-  2G: ADXL345_RANGE_2G   // +/-  4G: ADXL345_RANGE_4G   // +/-  8G: ADXL345_RANGE_8G   // +/- 16G: ADXL345_RANGE_16G   accel.setRange(ADXL345_RANGE_16G);                   checkActivitySetup();//开启单击、双击动作检测           // 用LED指示数据读取     pinMode(LED_PIN, OUTPUT); } void loop() { #if 0                 // 获取原始的X,Y,Z三轴的数据     accel.getAcceleration(&ax, &ay, &az);     // 显示 x/y/z 原始数值     Serial.print("accel:\t");     Serial.print(ax); Serial.print("\t");     Serial.print(ay); Serial.print("\t");     Serial.println(az);           #endif #if 1         //获取重力转换后的加速度数值         accel.readNormalize(&nx,&ny,&nz);                   //使用低通滤波进行处理,以去除尖峰的不准确结果         float fx, fy, fz;         //系数范围 0.1~0.9 //        accel.lowPassFilter(nx,ny,nz,&fx,&fy,&fz,0.5);                   Serial.print("gravity:\t");     Serial.print(nx); Serial.print("\t");     Serial.print(ny); Serial.print("\t");     Serial.println(nz); //         //        Serial.print("filter:\t"); //    Serial.print(fx); Serial.print("\t"); //    Serial.print(fy); Serial.print("\t"); //    Serial.println(fz); #endif #if 1         checkActivity();//单双击动作检测 #endif     // 闪烁LED     blinkState = !blinkState;     digitalWrite(LED_PIN, blinkState);                   delay(300); }复制代码 该应用代码包含传感器三个轴向的加速度和单击、双击的检测功能。 完整代码可到零知实验室官网免费获取。 3、结果 更多详细资料请到零知实验室官网免费获取。

  • 2019-05-21
  • 发表了主题帖: 零知开源分享-蓝牙模块与手机APP通信

    本帖最后由 roc2 于 2019-5-21 14:18 编辑 本篇文章中将讲解蓝牙模块与安卓手机APP进行通信。1、说明MCU:零知开发板-标准板模块:JDY-18蓝牙模块https://www.arduino.cn/data/attachment/forum/201905/21/115017y2cx6txnx1p1x2ct.png安卓手机:本次演示型号为荣耀102、电路连接模块引脚图如下:电路连接很简单,把TXD、RXD分别连接到标准板的0、1脚即可。https://www.arduino.cn/data/attachment/forum/201905/21/120017ikdovrbkrzzpn7ob.png3、调试核心代码:/** *    文件: jdy18-ble-test1.ino      by 零知实验室 *    -^^- 零知开源,让电子制作变得更简单! -^^- *    时间: 2018/08/09 10:36 *    说明: **/    // the setup routine runs once when you press reset: void setup() {     // put your setup code here, to run once:     Serial.begin(9600);     Serial1.begin(9600);           Serial1.println("AT+NAMEJDY-18TEST"); } // the loop routine runs over and over again forever: void loop() {     // put your main code here, to run repeatedly:     if(Serial1.available()>0){         char x = Serial1.read();         Serial.println(x); //      Serial1.print(x+1);     }     if(Serial.available()>0){         Serial1.print(Serial.read());     }     delay(100);           //Serial1.print("test"); }复制代码 把程序上传到零知标准板上,然后在手机上打开你的蓝牙调试APP,就可以与蓝牙模块进行通信了。更多详细资料可到零知实验室官网免费获取。 此内容由EEWORLD论坛网友roc2原创,如需转载或用于商业用途需征得作者同意并注明出处

最近访客

< 1/1 >

统计信息

已有13人来访过

  • 芯币:195
  • 好友:--
  • 主题:31
  • 回复:5
  • 课时:--
  • 资源:--

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言