当前位置: 首页 > news >正文

艹,终于在8226上把灯点亮了

接上次点文章

ESP8266还可以这样玩

这次,我终于学会了在ESP8266上面点亮LED灯了

现在一个单片机的价格是几块,加上一个晶振,再来一个快递费,十几块钱还是需要的。

所以能用这个ESP8266来当单片机玩,还是比较不错的

可以在ubuntu、windows、Macos上开发

来了,先点亮一个LED灯

LED灯的GPIO口是 16

直接看代码,我们现在看到的代码实际上已经是跑了freertos的,这也是我为什么不用ardino玩,脱离了C语言就好像已经不是在做嵌入式了,要想了解底层还是用C语言比较有亲切感。

看代码

/* Hello World Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
#define GPIO_LED_NUM 16

void app_main()
{
    printf("Hello world!\n");

    /* 1.定义一个gpio配置结构体 */
    gpio_config_t gpio_config_structure;

    /* 2.初始化gpio配置结构体*/
    gpio_config_structure.pin_bit_mask = (1ULL << GPIO_LED_NUM);/* 选择gpio2 */
    gpio_config_structure.mode = GPIO_MODE_OUTPUT; /* 输出模式 */
    gpio_config_structure.pull_up_en = 0; /* 不上拉 */
    gpio_config_structure.pull_down_en = 0; /* 不下拉 */
    gpio_config_structure.intr_type = GPIO_INTR_DISABLE; /* 禁止中断 */

    /* 3.根据设定参数初始化并使能 */
    gpio_config(&gpio_config_structure);

    /* 4.输出低电平,点亮LED*/
    gpio_set_level(GPIO_LED_NUM, 0);

    /* Print chip information */
    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    printf("This is ESP8266 chip with %d CPU cores, WiFi, ",
            chip_info.cores);

    printf("silicon revision %d, ", chip_info.revision);

    printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
            (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

    for (int i = 100000; i >= 0; i--) {
        printf("Restarting in %d seconds...\n", i);
        gpio_set_level(GPIO_LED_NUM, 0);
        vTaskDelay(500 / portTICK_PERIOD_MS);
        gpio_set_level(GPIO_LED_NUM, 1);
        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
    printf("Restarting now.\n");
    fflush(stdout);
    esp_restart();
}

70858ba5c8a4e82b124930b5c6fd6940.gif

LED是一个很入门的东西,但是LED也是一个很有意思的东西,如果玩得好可以变得很有趣。

本来想用这个GPIO口来做一个PWM控制的呼吸灯功能的,可惜查看了下手册,发现这个GPIO16口没有PWM功能。

86a0df1a1a1b0252784d71a1ad515cfc.png

再来搞一个程序

扫描附近的wifi,如果搞好了继续往深的玩,可以做一个这样的设备,专门用来扫描附近的热点,然后用随机密码连接,连接上了打印密码,是不是也很酷。

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"

static EventGroupHandle_t wifi_event_group;//定义一个事件的句柄
const int SCAN_DONE_BIT = BIT0;//定义事件,占用事件变量的第0位,最多可以定义32个事件。
static wifi_scan_config_t scanConf = { //定义scanConf结构体,供函数esp_wifi_scan_start调用
    .ssid = NULL,
    .bssid = NULL,
    .channel = 0,
    .show_hidden = 1
};

static const char *TAG = "example";

esp_err_t event_handler(void *ctx, system_event_t *event)
{
    if (event->event_id == SYSTEM_EVENT_SCAN_DONE) {
        xEventGroupSetBits(wifi_event_group, SCAN_DONE_BIT); //设置事件位
    }
    return ESP_OK;
}

static void initialise_wifi(void)        //define a static function ,it's scope is this file
{
    wifi_event_group = xEventGroupCreate(); //创建一个事件标志组
    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));//创建事件的任务
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();//设置默认的wifi栈参数
    ESP_ERROR_CHECK(esp_wifi_init(&cfg)); //初始化WiFi Alloc资源为WiFi驱动,如WiFi控制结构,RX / TX缓冲区,WiFi NVS结构等,此WiFi也启动WiFi任务。
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));// Set the WiFi API configuration storage type
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));//Set the WiFi operating mode
    ESP_ERROR_CHECK(esp_wifi_start());
}

static void scan_task(void *pvParameters)
{
    while(1) {
        xEventGroupWaitBits(wifi_event_group, SCAN_DONE_BIT, 0, 1, portMAX_DELAY); //等待事件被置位,即等待扫描完成
        ESP_LOGI(TAG, "WIFI scan doen");
        xEventGroupClearBits(wifi_event_group, SCAN_DONE_BIT);//清除事件标志位

        uint16_t apCount = 0;
        esp_wifi_scan_get_ap_num(&apCount);//Get number of APs found in last scan
        printf("Number of access points found: %d\n", apCount);
        if (apCount == 0) {
            ESP_LOGI(TAG, "Nothing AP found");
            return;
        }//如果apCount没有受到数据,则说明没有路由器
        wifi_ap_record_t *list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);//定义一个wifi_ap_record_t的结构体的链表空间
        ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, list));//获取上次扫描中找到的AP列表。
        int i;
        printf("======================================================================\n");
        printf(" SSID | RSSI | AUTH \n");
        printf("======================================================================\n");
        for (i=0; i<apCount; i++) {
            char *authmode;
            switch(list[i].authmode) {
            case WIFI_AUTH_OPEN: authmode = "WIFI_AUTH_OPEN";
               break;
            case WIFI_AUTH_WEP: authmode = "WIFI_AUTH_WEP";
               break;
            case WIFI_AUTH_WPA_PSK: authmode = "WIFI_AUTH_WPA_PSK";
               break;
            case WIFI_AUTH_WPA2_PSK: authmode = "WIFI_AUTH_WPA2_PSK";
               break;
            case WIFI_AUTH_WPA_WPA2_PSK: authmode = "WIFI_AUTH_WPA_WPA2_PSK";
               break;
            default: authmode = "Unknown";
               break;
            }
            printf("%26.26s | % 4d | %22.22s\n",list[i].ssid, list[i].rssi, authmode);
        }//将链表的数据信息打印出来
        free(list);//释放链表
        printf("\n\n");//换行

        // scan again
        vTaskDelay(2000 / portTICK_PERIOD_MS);//调用延时函数,再次扫描
        //The true parameter cause the function to block until the scan is done.
        ESP_ERROR_CHECK(esp_wifi_scan_start(&scanConf, 1));//扫描所有可用的AP。
    }


}

int app_main(void)
{
    nvs_flash_init();//初始化NVS flash storage
    tcpip_adapter_init();//初始化i本机TCP/IP协议
    initialise_wifi();//初始化wifi

    xTaskCreate(&scan_task, "scan_task", 2048, NULL, 15, NULL);//创建扫描任务

    ESP_ERROR_CHECK(esp_wifi_scan_start(&scanConf, 1)); //The true parameter cause the function to block until
                                                              //the scan is done.
    return 0;
}

运行的情况是

c8496ba90c09731bdc2cb24811963d08.png

8226可以玩的东西还有很多,比如内存、Flash、I2C、SPI

因为我对LED灯还是不死心,就买了一些LED灯回来,等到货了继续给大家看看呼吸灯。

好了,我的商店也上了20个这样的ESP8266,喜欢的可以去看看吧。

现在只有20个的ESP8266

e2c794cf571622e2a56817e3f6250427.jpeg

11e64e9437f1cc20d34cb41a49703673.jpeg

da1bb589da8e6b5e467a0d936a36f3e8.png

相关文章:

  • Linux上用Samba建立共享文件夹并通过Linux测试
  • shell简单使用介绍
  • 关于中级开发工程师常问的面试题
  • 蓝桥杯刷题第二十天
  • 二叉树(数据结构系列9)
  • mybatis-plus的批量新增insertBatchSomeColumn
  • Linux内核IO基础知识与概念
  • Java - 配置中心初体验
  • 面试--每日一经
  • 算法训练营第五十九天|LeetCode647、516
  • 音视频开发—MediaCodec 解码H264/H265码流视频
  • 【python进阶】序列切片还能这么用?切片的强大比你了解的多太多
  • 内网升级“高效安全”利器!统信软件发布私有化更新管理平台
  • 什么是Vue
  • [图像识别]关于cv2库无法安装的故障问题解决,全网最全解决方案!本人亲身测试,参考了stackoverflow、51CTO等博客文章总结而成
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【刷算法】求1+2+3+...+n
  • 2017 前端面试准备 - 收藏集 - 掘金
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • 3.7、@ResponseBody 和 @RestController
  • eclipse的离线汉化
  • Netty 4.1 源代码学习:线程模型
  • PAT A1017 优先队列
  • Vue官网教程学习过程中值得记录的一些事情
  • Windows Containers 大冒险: 容器网络
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 大主子表关联的性能优化方法
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 力扣(LeetCode)965
  • 漂亮刷新控件-iOS
  • 前端性能优化——回流与重绘
  • 微信小程序:实现悬浮返回和分享按钮
  • 协程
  • 用jquery写贪吃蛇
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • 如何正确理解,内页权重高于首页?
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​TypeScript都不会用,也敢说会前端?
  • #stm32整理(一)flash读写
  • (ibm)Java 语言的 XPath API
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转)Google的Objective-C编码规范
  • (转)http-server应用
  • .net framework4与其client profile版本的区别
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET简谈设计模式之(单件模式)
  • .net快速开发框架源码分享
  • .NET轻量级ORM组件Dapper葵花宝典
  • ?.的用法