部分_compressed.jpg (352.69 KB, 下載次數: 67)
下載附件
2018-5-19 07:34 上傳
工作流程
流程圖.png (26.19 KB, 下載次數: 76)
下載附件
2018-5-19 08:58 上傳
自適應傳輸速率以及譯碼傳輸速率: M /--/ M和O的電碼 O /---/
↓下圖為MO的電碼片段
小圖.png (9.18 KB, 下載次數: 66)
下載附件
2018-5-19 08:59 上傳
由圖可見字母M是由 LL HL LS HL 組成,而LL是所謂的數據頭(時間比較長的低電平狀態) 為了識別出信號的長短,我們首先需要知道信號長短的時間,于是乎我們可以在開機時進行一定量的數據采樣,因為每個完整的信號短都包含了長和短的情況,可以計算出長和短信號時間的平均值,根據這個平均值對長短信號分兩個數列存儲,最后用平滑算法算出大概的延遲時間,這樣就做到自動確定通訊速率!
譯碼: 由上文可知,我們獲取到了信號長短的延遲,并且能夠對比長短和電平來識別出數據 當檢測到數據頭后假如存在上一個字符的緩存會進行翻譯。 翻譯過程就是根據LS,HS,HL狀態分為0,1,2 然后對比碼庫
如果沒有存在緩存,那么進行從檢測到數據頭開始把接收到的信號存儲在緩存里
電路圖
電路圖_壓縮.jpg (50.03 KB, 下載次數: 72)
下載附件
2018-5-19 08:58 上傳
源碼:
- /*=========================================================
- LHW開發
- oled下半部分是留空的,計劃用于顯示數據圖表,不過現在優化做的不太好,如果實時刷新數據圖表會導致系統資源緊張,做不到實時采樣,導致無法抄收完整數據,我很頭疼,現在通訊速率收到這個限制,搞到每個字符傳輸速度不得快于60ms
- 如果有好的優化方案,歡迎聯系
- 重要 開機的時候信號口必須有信號然后在開機,因為開機后會自動學習和分析信號并自動調整速率,否則輸出會與發送的不符
- =========================================================*/
- #include "U8glib.h"//引用U8G頭文件
- U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);//設置設備名稱:I2C-SSD1306-128*64(OLED)
- //如果屏幕不同請自行修改 如果第一次使用u8glib并且遇到顯示不正確,請自行修改u8g配置
- /*=========================================================
- 變量
- =========================================================*/
- int x, y; int Buffer[128]; //
- int Time = 0; //計時
- int DPin = A0; //數據接收口
- byte RXB[10]; //接收緩沖區 0為中間間隔 1為短高 2為長高
- int SA[10]; //初始數據平均值
- int DA;
- int HH[10]; //平滑數據 最高的長度
- int AH, AL; //平滑后的數據
- byte TH, TT, TRX, MT; //位置
- bool ET = false; //電平是否變化
- byte BootOk = 0; //初始化階段 0為學習通訊速率 1為計算基準值 2為完成通訊速率學習 3為檢測到數據起始符 4為工作狀態
- byte DFT = 35; //數據正方向容錯值
- bool WI = false; //工作狀態
- //碼庫
- long MH[36] = {
- 1020202020,
- 1010202020,
- 1010102020,
- 1010101020,
- 1010101010,
- 2010101010,
- 2020101010,
- 2020201010,
- 2020202010,
- 2020202020,
- 1020000000,
- 2010101000,
- 2010201000,
- 2010100000,
- 1000000000,
- 1010201000,
- 2020100000,
- 1010101000,
- 1010000000,
- 1020202000,
- 2010200000,
- 1020101000,
- 2020000000,
- 2010000000,
- 2020200000,
- 1020201000,
- 2020102000,
- 1020100000,
- 1010100000,
- 2000000000,
- 1010200000,
- 1010102000,
- 1020200000,
- 2010102000,
- 2010202000,
- 2020101000
- };
- char ME[36] = {
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- };
- char MS[32] = {49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,}; //信息顯示區
- /*=========================================================
- 只循環一次
- =========================================================*/
- void setup()
- {
- pinMode(DPin, INPUT); //初始化接收pin口
- Serial.begin(115200); //初始化串口比特率
- u8g.setFont(u8g_font_04b_03r);
- u8g.firstPage();
- do {
- u8g.setPrintPos(13, 33);
- u8g.print("Automatic detection rate");
- } while ( u8g.nextPage() );
- }
- /*=========================================================
- 不停循環
- =========================================================*/
- void loop()
- {
- scanning(); //掃描
- }
- /*=========================================================
- 顯示
- =========================================================*/
- void Draw() {
- u8g.firstPage();
- do {
- int i = 0;
- for (int py = 0; py < 2; py++) {
- for (int px = 0; px < 16; px++) {
- u8g.setPrintPos(px * 8 + 2, py * 8 + 6);
- u8g.print((char)MS[i]);
- i++;
- }
- }
- } while ( u8g.nextPage() );
- }
- /*=========================================================
- 清除數據緩沖
- =========================================================*/
- void CM() {
- for (int i = 0; i < 10; i++) RXB[i] = 0;
- }
- /*=========================================================
- 起始符處理
- =========================================================*/
- void Tse() {
- //檢測到數據起始符
- String TXT;
- for (int i = 0; i < 10; i++) { //把接收區緩存合成字符串
- TXT = TXT + RXB[i];
- }
- Serial.println(TXT);
- for (int i = 0; i < 35; i++) { //匹配數據庫信號
- if (String(MH[i]) == TXT) {
- MS[MT] = ME[i]; //把信息寫入 顯示緩沖 區
- MT++;
- if (MT > 31) MT = 0; //如果顯示區溢出,覆蓋舊的信息
- Draw();
- }
- }
- CM(); //清除接收區緩存
- TRX = 0; //接收區緩存地址重置
- }
- /*=========================================================
- 譯碼
- =========================================================*/
- void translation()
- {
- if (Time >= AH - DFT && Time <= AH + DFT && !ET) {
- Tse();
- } else {
- if (TRX > 9) TRX = 0; //數據接收錯誤 初始化
- if (!ET) { //低電平
- if (Time >= AL - DFT && Time <= AL + DFT) {
- RXB[TRX] = 0;
- TRX++;
- }
- } else {
- if (Time >= AL - DFT && Time <= AL + DFT) {
- RXB[TRX] = 1;
- TRX++;
- } else {
- if (Time >= AL + DFT && Time <= AH + DFT) {
- RXB[TRX] = 2;
- TRX++;
- }
- }
- }
- }
- }
- /*=========================================================
- 掃描
- =========================================================*/
- void scanning() {
- if (digitalRead(DPin) != ET) { //電平發生改變
- Time = 0; //重置計時
- ET = digitalRead(DPin); //重置電平狀態
- while (digitalRead(DPin) == ET) { //檢測電平是否再次改變
- if (Time >= 10000) { //大于10秒接收超時
- /* Serial.print(millis());
- Serial.println(" : TimeOut !");*/
- goto EndRx; //超時
- }
- if (RXB[TRX - 1] != 0 && Time >= AH + 30) {
- //可能是通訊結尾 并且不會再有數據傳送
- Tse();
- }
- Time++; //增加計時
- delay(1); //延時1ms
- }
- EndRx:
- if (Time < 10000) {
- //如果沒有超時
- Serial.print(millis());
- Serial.print(" : ");
- Serial.print(ET);
- Serial.print(" ");
- Serial.println(Time);
- //學習波形
- if (BootOk == 0) {
- SA[TH] = Time;
- if (TH > 8) {
- BootOk = 1;
- } else {
- TH++;
- }
- } else {
- if (BootOk == 1) {
- //計算信號基準值
- for (int i = 0; i < 10; i++) DA = DA + SA[i]; //相加
- DA = float(DA / 10); //獲取平均值
- BootOk++;
- } else {
- if (BootOk == 2) {
- if (Time > DA) {
- HH[TT] = Time; //寫入最高平滑
- TT++;
- if (TT > 9) {
- TT = 0;
- AH = 0;
- for (int i = 0; i < 10; i++) AH = AH + HH[i]; //相加
- AH = float(AH / 10); //獲取平均值
- AL = float(AH / 3); //獲取平均值
- BootOk++;
- }
- }
- } else {
- translation(); //譯碼
- }
- }
- }
- }
- }
- }
復制代碼
全部資料51hei下載地址:
RX.zip
(2.6 KB, 下載次數: 39)
2018-5-19 09:10 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|