|
本帖最后由 mmuyu 于 2023-9-15 20:19 编辑
1.项目分析: 由于8266引脚较少,并且根据安信可提供的规格书,io口电流无法提供达到继电器要求的电流,使用灌电流驱动大概率烧坏芯片,因此我们选择使用74hc595实现3个io口驱动8路继电器,74hc595至少每个io口能提供1ma以上的电流,经过三极管放大后可以满足我们驱动继电器的要求。
2.8266引脚分配:
根据esp12-f规格书,避开已经被芯片内部使用的,以及与启动重启相关的gpio口,为设备需要的重启,下载模式切换,led灯,595驱动引脚,串口等重要功能预先分配好需要用到的gpio口,方便后续绘制原理图。此项目的GPIO口分配如下:
3.原理图绘制:
根据io口分配,绘制功能电路,供电电路以及其他**电路。此项目使用立创EDA专业版设计,为考虑手工焊接,元器件价格和方便购买,大部分元器件选用立创smt基础库元器件,规格大部分为1206,SOT-223之类较大的封装。
4.元器件选型要求:
1.自恢复保险丝用于esp8266供电用,esp-12f规格书提及esp8266的电流最大会大于500ma,因此元器件选型的时候,保险丝跳闸电流要大于500ma。
2.确认继电器参数是否与三极管匹配,避免烧坏三极管
5.布线-打板-焊接:
布线注意事项:继电器常用于驱动大功率电器,要确保线宽符合设备电流要求。
打板:此项目使用嘉立创免费打样,为保证pcb能按设计要求生产,尽量在打板前进行DFM检查。
项目实物图:
6.设备创建(soc模式)-编辑数据点:
详细数据点会在文末给出
7.代码编写:
考虑文章篇幅,仅给出重要代码,稍后会整理项目打包放到帖子里
按键重定义:
- #define GPIO_KEY_NUM 1 ///< Defines the total number of key members
- #define KEY_0_IO_MUX PERIPHS_IO_MUX_GPIO4_U ///< ESP8266 GPIO function
- #define KEY_0_IO_NUM 4 ///< ESP8266 GPIO number
- #define KEY_0_IO_FUNC FUNC_GPIO4 ///< ESP8266 GPIO name
- singleKey[0] = keyInitOne(KEY_0_IO_NUM, KEY_0_IO_MUX, KEY_0_IO_FUNC,
- key2LongPress, key2ShortPress);
复制代码
595管脚初始化:
- void Init_74hc595_gpio(void){
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13);
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14);
- GIZWITS_LOG( "success init 74hc595 gpio\n");
- }
复制代码
595驱动:
- uint8_t relay_data[]={0,0,0,0,0,0,0,0};
- void Ctrl_74hc595(uint8_t data[]){
- int i=7;
- HC595_RCK(0);
- os_delay_us(1);
- for(i=8;i>=0;i--){
- HC595_SCK(0);
- os_delay_us(1);
- if(data[i]==0){
- HC595_DATA(0);
- }else{
- HC595_DATA(1);
- }
- os_delay_us(1);
- HC595_SCK(1);
- }
- os_delay_us(1);
- HC595_RCK(1);
- }
复制代码
继电器全开:
- void All_relay_on(uint8_t data[]){
- int i=0;
- for(i=0;i<8;i++){
- data[i]=1;
- }
- }
复制代码
事件处理:
- case EVENT_ALL_RELAY_ON :
- currentDataPoint.valueALL_RELAY_ON = dataPointPtr->valueALL_RELAY_ON;
- GIZWITS_LOG("Evt: EVENT_ALL_RELAY_ON %d \n", currentDataPoint.valueALL_RELAY_ON);
- if(0x01 == currentDataPoint.valueALL_RELAY_ON)
- {
- //user handle
- All_relay_on(relay_data);
- Ctrl_74hc595(relay_data);
- currentDataPoint.valueRELAY_1_ONOFF=1;
- currentDataPoint.valueRELAY_2_ONOFF=1;
- currentDataPoint.valueRELAY_3_ONOFF=1;
- currentDataPoint.valueRELAY_4_ONOFF=1;
- currentDataPoint.valueRELAY_5_ONOFF=1;
- currentDataPoint.valueRELAY_6_ONOFF=1;
- currentDataPoint.valueRELAY_7_ONOFF=1;
- currentDataPoint.valueRELAY_8_ONOFF=1;
- }
- else
- {
- //user handle
- }
- break;
- case EVENT_RELAY_1_ONOFF :
- currentDataPoint.valueRELAY_1_ONOFF = dataPointPtr->valueRELAY_1_ONOFF;
- GIZWITS_LOG("Evt: EVENT_RELAY_1_ONOFF %d \n", currentDataPoint.valueRELAY_1_ONOFF);
- if(0x01 == currentDataPoint.valueRELAY_1_ONOFF)
- {
- //user handle
- relay_data[0]=1;
- Ctrl_74hc595(relay_data);
- }
- else
- {
- relay_data[0]=0;
- Ctrl_74hc595(relay_data);
- currentDataPoint.valueALL_RELAY_ON=0;
- //user handle
- }
- break;
复制代码
上电初始化:
- void ICACHE_FLASH_ATTR userInit(void)
- {
- gizMemset((uint8_t *)¤tDataPoint, 0, sizeof(dataPoint_t));
- /** Warning !!! DataPoint Variables Init , Must Within The Data Range **/
- currentDataPoint.valueALL_RELAY_ON = 0;
- currentDataPoint.valueRELAY_1_ONOFF = relay_data[0];
- currentDataPoint.valueRELAY_2_ONOFF = relay_data[1];
- currentDataPoint.valueRELAY_3_ONOFF = relay_data[2];
- currentDataPoint.valueRELAY_4_ONOFF = relay_data[3];
- currentDataPoint.valueRELAY_5_ONOFF = relay_data[4];
- currentDataPoint.valueRELAY_6_ONOFF = relay_data[5];
- currentDataPoint.valueRELAY_7_ONOFF = relay_data[6];
- currentDataPoint.valueRELAY_8_ONOFF = relay_data[7];
- Ctrl_74hc595(relay_data);
- }
复制代码
8.代码烧录:
项目已做好下载模式切换和串口切换
烧录模式:切换启动模式按钮到接地端,同时使用排帽连接ch340c的tx rx到芯片rx tx
串口输出模式:仅使用一个排帽连接uart1 tx和ch340c rx即可
9.设备配网:
设备的key2用于设备配网,长按即可启动airlink配网模式,同时对应led2会亮起。
10.实际演示:
这里使用led灯用于展示,因为继电器自身吸合有声音,因此原理图不放置led灯展示继电器状态。
项目开源地址:
|
|