找回密码
 立即注册
查看: 1114|回复: 8

慢搓PELCO_D解码板

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:126
  • 最近打卡:2025-05-22 13:08:44

15

主题

62

回帖

510

积分

高级会员

积分
510
发表于 2024-3-5 19:01:34 | 显示全部楼层 |阅读模式
最近想做个远程浇水的摄像头,以便管理老家的瓜瓜果果,斥巨资160买了个安佳MTJ40D摄像头模组,让店家刷了可以输出PELCO_D云台协议的固件,
可是PELCO_D云台协议的解码板实在太贵,都在200+,决定自己慢搓。
今天模组到手,组装起来。

微信图片_20240305185304.jpg

解码还是用STC8H8K64U, 24MHZ晶振,
串口1用于ISP和仿真
串口2  
RXD2 用于接收摄像头发过来的PELCO_D协议数据,
TXD2 用于向STC-ISP发送收到的数据
波特率设置为9600_8_N_1
目前测试正常
微信图片_20240305184707.png


下一步慢慢研究PELCO_D协议,对接收的数据进行解码,输出相应动作。

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-07-01 11:02:05
已绑定手机

14

主题

1322

回帖

3428

积分

论坛元老

积分
3428
发表于 2024-3-5 20:25:34 | 显示全部楼层
有实践、应用,才能更好掌握。
话说,远程浇水用摄像头干什么呢?能否大概介绍一下原理
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:126
  • 最近打卡:2025-05-22 13:08:44

15

主题

62

回帖

510

积分

高级会员

积分
510
发表于 2024-3-5 21:49:19 | 显示全部楼层
21cns*** 发表于 2024-3-5 20:25
有实践、应用,才能更好掌握。
话说,远程浇水用摄像头干什么呢?能否大概介绍一下原理 ...

可以巡查地里的情况,看作物生长得怎么样了,手动浇水。

例如这个摄像头的上下左右键对应4个喷头,看到农作物有点旱的话直接按云台上的方向键喷水就可以了。
微信图片_20240305214327.jpg



如果用在养鸡养鸽子,那就是把玉米,稻谷,豆粕等饲料加到食槽。

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-07-01 11:02:05
已绑定手机

14

主题

1322

回帖

3428

积分

论坛元老

积分
3428
发表于 2024-3-5 21:56:11 | 显示全部楼层
hl12*** 发表于 2024-3-5 21:49
可以巡查地里的情况,看作物生长得怎么样了,手动浇水。

例如这个摄像头的上下左右键对应4个喷头,看到 ...

通过单片机远程控制云台、水管电磁阀门,通过摄像头观察是否需要浇水,是吧?
如果是这样,还可以进一步,在土壤中安装土壤湿度传感器自动控制电磁阀门。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:126
  • 最近打卡:2025-05-22 13:08:44

15

主题

62

回帖

510

积分

高级会员

积分
510
发表于 2024-3-6 08:22:28 | 显示全部楼层
21cns*** 发表于 2024-3-5 21:56
通过单片机远程控制云台、水管电磁阀门,通过摄像头观察是否需要浇水,是吧?
如果是这样,还可以进一步 ...

那是进一步的事情了,先搞好远程手控先。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:126
  • 最近打卡:2025-05-22 13:08:44

15

主题

62

回帖

510

积分

高级会员

积分
510
发表于 2024-3-6 16:35:00 | 显示全部楼层
PELCO_D协议

pelco-d.pdf (32.88 KB, 下载次数: 122)
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:126
  • 最近打卡:2025-05-22 13:08:44

15

主题

62

回帖

510

积分

高级会员

积分
510
发表于 2024-3-6 16:53:51 | 显示全部楼层

The format for a message is:

Byte 1             Byte 2         Byte 3                Byte 4                Byte 5      Byte 6      Byte 7
Synch Byte     Address      Command 1       Command 2       Data 1      Data 2      Check Sum



All values below are shown in hexadecimal (base 16).
The synchronization byte is always $FF.


The address is the logical address of the receiver/driver being controlled.
The check sum is the 8 bit (modulo 256) sum of the payload bytes (bytes 2 through 6) in the message.


消息数据格式
字节 1                字节 2        字节 3           字节 4       字节 5     字节 6     字节 7
同步码(0xff)     地址           指令1             指令2        数据1      数据2      校验和

所有的数据以16进制显示
同步码为0xff
地址是被控制接收器/驱动器的逻辑地址
校验和是消息负载位(2-6字节)8位(模256)和。







回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:126
  • 最近打卡:2025-05-22 13:08:44

15

主题

62

回帖

510

积分

高级会员

积分
510
发表于 2024-3-6 18:54:57 | 显示全部楼层
使用实验箱的例程改出接收程序,正常接收到协议数据,并且能保存到数组。


  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* --- Mobile: (86)13922805190 ----------------------------------------*/
  5. /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
  6. /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
  7. /* --- Web: www.STCAI.com ---------------------------------------------*/
  8. /* --- Web: www.STCMCUDATA.com  ---------------------------------------*/
  9. /* --- BBS: www.STCAIMCU.com  -----------------------------------------*/
  10. /* --- QQ:  800003751 -------------------------------------------------*/
  11. /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
  12. /*---------------------------------------------------------------------*/
  13. /*************  功能说明    **************
  14. 本例程基于STC8H8K64U为主控芯片的实验箱9进行编写测试,STC8G、STC8H系列芯片可通用参考.
  15. 串口2全双工中断方式收发通讯程序。
  16. 通过PC向MCU发送数据, MCU收到后通过串口2把收到的数据原样返回.
  17. 用定时器做波特率发生器,建议使用1T模式(除非低波特率用12T),并选择可被波特率整除的时钟频率,以提高精度。
  18. 下载时, 选择时钟 22.1184MHz (用户可自行修改频率).
  19. ******************************************/
  20. #include "../comm/stc8h.h"
  21. #include "intrins.h"
  22. #include "pelco_d.h"
  23. #define MAIN_Fosc       24000000L   //定义主时钟(精确计算115200波特率)
  24. typedef     unsigned char   u8;
  25. typedef     unsigned int    u16;
  26. typedef     unsigned long   u32;
  27. #define Baudrate2   9600L
  28. #define UART2_BUF_LENGTH    64
  29. u8  TX2_Cnt;    //发送计数
  30. u8  RX2_Cnt;    //接收计数
  31. bit B_TX2_Busy; //发送忙标志
  32. u8  xdata RX2_Buffer[UART2_BUF_LENGTH]; //接收缓冲
  33. u8 pelco_d_num = 0;
  34. u8 pelco_d_r[8] = 0;
  35. u8 pelco_d_to = 0;
  36. u8 pelco_d_c;
  37. void UART2_config(u8 brt);   // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  38. void PrintString2(u8 *puts);
  39. void PrintPelcoD(void);
  40. //========================================================================
  41. // 函数: void main(void)
  42. // 描述: 主函数。
  43. // 参数: none.
  44. // 返回: none.
  45. // 版本: VER1.0
  46. // 日期: 2014-11-28
  47. // 备注:
  48. //========================================================================
  49. void pelco_d_main(void)
  50. {
  51.     P_SW2 |= 0x80;  //扩展寄存器(XFR)访问使能
  52.     //P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  53.     //P1M1 = 0x30;   P1M0 = 0x30;   //设置P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V)
  54.     //P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V)
  55.     //P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  56.     //P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  57.     //P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  58.     //P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  59.     //P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  60.         P1M1 = 0x00;   P1M0 = 0x00;
  61.         XOSCCR = 0xc0;  //启动外部晶振
  62.         while(!(XOSCCR & 0x01));  //等待时钟稳定
  63.         CLKDIV = 0x00;  //时钟不分频
  64.         CLKSEL = 0x01; //选择外部晶振
  65.     UART2_config(2);    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  66.     EA = 1; //允许全局中断
  67.    
  68.     PrintString2("STC8H8K64U UART2 Test Programme!\r\n");  //UART2发送一个字符串
  69.         pelco_d_r[7] = 0;
  70.     while (1)
  71.     {
  72.         if((TX2_Cnt != RX2_Cnt) && (!B_TX2_Busy))   //收到数据, 发送空闲
  73.         {
  74.             //S2BUF = RX2_Buffer[TX2_Cnt];
  75.                         pelco_d_c = RX2_Buffer[TX2_Cnt];
  76.             //B_TX2_Busy = 1;
  77.             if(++TX2_Cnt >= UART2_BUF_LENGTH)   TX2_Cnt = 0;
  78.                         //超时,接收归零
  79.                         //if(pelco_d_to > 100)
  80.                         //{
  81.                         //    pelco_d_num = 0;
  82.                         //}
  83.                        
  84.                        
  85.                         //在空闲状态下收到0xff,则进入等待状态。
  86.                         /*if(pelco_d_num == 0)
  87.                         {
  88.                             if(RX2_Buffer[TX2_Cnt] == 0xff)
  89.                             {
  90.                                 pelco_d_r[pelco_d_num] = 0xff;
  91.                                     pelco_d_num = 1;
  92.                             }
  93.                         }
  94.                         */
  95.                         if(pelco_d_c == 0xff)
  96.                         {
  97.                             pelco_d_r[0] = 0xff;
  98.                                 pelco_d_num = 1;
  99.                         }
  100.                         //在等待状态下,接收到的新字节放到数组,num递增,7个后归零
  101.                         else if(pelco_d_num > 0)
  102.                         {
  103.                             pelco_d_r[pelco_d_num] =  pelco_d_c;
  104.                                 pelco_d_num ++;
  105.                                 if(pelco_d_num > 6)
  106.                                 {
  107.                                     pelco_d_num = 0;
  108.                                         PrintString2("pelco_d data is:");
  109.                                         PrintPelcoD();
  110.                                         PrintString2("\r\n");
  111.                                 }   
  112.                         }
  113.                        
  114.         }
  115.     }
  116. }
  117. //========================================================================
  118. // 函数: void PrintString2(u8 *puts)
  119. // 描述: 串口2发送字符串函数。
  120. // 参数: puts:  字符串指针.
  121. // 返回: none.
  122. // 版本: VER1.0
  123. // 日期: 2014-11-28
  124. // 备注:
  125. //========================================================================
  126. void PrintString2(u8 *puts)
  127. {
  128.     for (; *puts != 0;  puts++)     //遇到停止符0结束
  129.     {
  130.         while(B_TX2_Busy);
  131.                 S2BUF = *puts;
  132.         B_TX2_Busy = 1;
  133.         while(B_TX2_Busy);
  134.     }
  135. }
  136. //========================================================================
  137. // 函数:
  138. // 描述:
  139. // 参数:
  140. // 返回:
  141. // 版本:
  142. // 日期:
  143. // 备注:
  144. //========================================================================
  145. void PrintPelcoD(void)
  146. {
  147.     u8 i = 0;
  148.         for (; i<7; i++)     //遇到停止符0结束
  149.     {
  150.         while(B_TX2_Busy);
  151.                
  152.                 S2BUF = '0';
  153.         B_TX2_Busy = 1;
  154.         while(B_TX2_Busy);
  155.                
  156.                 S2BUF = 'x';
  157.         B_TX2_Busy = 1;
  158.         while(B_TX2_Busy);
  159.                 if((pelco_d_r[i]/16) > 9)
  160.                 {
  161.                     S2BUF = ('a' + (pelco_d_r[i]/16) - 10);
  162.                 }
  163.                 else
  164.                 {
  165.                     S2BUF = ('0' + (pelco_d_r[i]/16));
  166.                 }
  167.         B_TX2_Busy = 1;
  168.         while(B_TX2_Busy);
  169.                 if((pelco_d_r[i]%16) > 9)
  170.                 {
  171.                     S2BUF = ('a' + (pelco_d_r[i]%16) - 10);
  172.                 }
  173.                 else
  174.                 {
  175.                     S2BUF = ('0' + (pelco_d_r[i]%16));
  176.                 }
  177.         B_TX2_Busy = 1;
  178.         while(B_TX2_Busy);
  179.                 S2BUF = ' ';
  180.         B_TX2_Busy = 1;
  181.         while(B_TX2_Busy);
  182.     }
  183. }
  184. //========================================================================
  185. // 函数: SetTimer2Baudraye(u16 dat)
  186. // 描述: 设置Timer2做波特率发生器。
  187. // 参数: dat: Timer2的重装值.
  188. // 返回: none.
  189. // 版本: VER1.0
  190. // 日期: 2014-11-28
  191. // 备注:
  192. //========================================================================
  193. void SetTimer2Baudraye(u16 dat)  // 使用Timer2做波特率.
  194. {
  195.     AUXR &= ~(1<<4);    //Timer stop
  196.     AUXR &= ~(1<<3);    //Timer2 set As Timer
  197.     AUXR |=  (1<<2);    //Timer2 set as 1T mode
  198.     T2H = dat / 256;
  199.     T2L = dat % 256;
  200.     IE2  &= ~(1<<2);    //禁止中断
  201.     AUXR |=  (1<<4);    //Timer run enable
  202. }
  203. //========================================================================
  204. // 函数: void UART2_config(u8 brt)
  205. // 描述: UART2初始化函数。
  206. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  207. // 返回: none.
  208. // 版本: VER1.0
  209. // 日期: 2014-11-28
  210. // 备注:
  211. //========================================================================
  212. void UART2_config(u8 brt)    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  213. {
  214.     /*********** 波特率固定使用定时器2 *****************/
  215.     if(brt == 2)
  216.     {
  217.         SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / Baudrate2);
  218.         S2CON &= ~(1<<7);   // 8位数据, 1位起始位, 1位停止位, 无校验
  219.         IE2   |= 1;         //允许中断
  220.         S2CON |= (1<<4);    //允许接收
  221.         P_SW2 &= ~0x01;
  222.         P_SW2 |= 0;         //UART2 switch to: 0: P1.0 P1.1,  1: P4.6 P4.7
  223.         B_TX2_Busy = 0;
  224.         TX2_Cnt = 0;
  225.         RX2_Cnt = 0;
  226.     }
  227. }
  228. //========================================================================
  229. // 函数: void UART2_int (void) interrupt UART2_VECTOR
  230. // 描述: UART2中断函数。
  231. // 参数: nine.
  232. // 返回: none.
  233. // 版本: VER1.0
  234. // 日期: 2014-11-28
  235. // 备注:
  236. //========================================================================
  237. void UART2_int (void) interrupt 8
  238. {
  239.     if((S2CON & 1) != 0)
  240.     {
  241.         S2CON &= ~1;    //Clear Rx flag
  242.         RX2_Buffer[RX2_Cnt] = S2BUF;
  243.         if(++RX2_Cnt >= UART2_BUF_LENGTH)   RX2_Cnt = 0;
  244.     }
  245.     if((S2CON & 2) != 0)
  246.     {
  247.         S2CON &= ~2;    //Clear Tx flag
  248.         B_TX2_Busy = 0;
  249.     }
  250. }
复制代码


微信图片_20240306185412.png
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:126
  • 最近打卡:2025-05-22 13:08:44

15

主题

62

回帖

510

积分

高级会员

积分
510
发表于 2024-3-17 10:53:13 | 显示全部楼层
抽空画了一个接口板

PCB_PCB1_2024-03-17.pdf (653.19 KB, 下载次数: 108)
微信图片_20240317104722.png
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-7-1 23:40 , Processed in 0.140917 second(s), 95 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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