標(biāo)題: arduino TFT彩屏示波器v2.0正式版源程序+電路圖 [打印本頁]

作者: 544919169    時間: 2019-3-31 15:22
標(biāo)題: arduino TFT彩屏示波器v2.0正式版源程序+電路圖
更新內(nèi)容
1,增加觸屏操作功能,所有操作直接通過觸屏操作
2,硬件部分增加負(fù)電壓采集功能。
3,探頭提供x1,x10,x100三檔衰減功能.
4,支持DC,AC藕合方式。
5,支持時基調(diào)。
6,增加HOLD功能。
演示:下圖采集的正玄波為市電通過9V變壓器降壓后直接采樣的波形。
有能力的朋友可以改進一下,最好能發(fā)份改進的源碼給我。

電路原理圖如下:


制作出來的實物圖如下:


單片機源程序如下:

  1. #include <Adafruit_GFX.h>
  2. #include <MCUFRIEND_kbv.h>
  3. #include <TouchScreen.h>
  4. MCUFRIEND_kbv tft;

  5. const int XP=7,XM=A1,YP=A2,YM=6; //ID=0x5408
  6. const int TS_LEFT=772,TS_RT=151,TS_TOP=953,TS_BOT=156;
  7. TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
  8. TSPoint tp;

  9. #define MINPRESSURE 200
  10. #define MAXPRESSURE 1000

  11. // 顏色值:
  12. #define BLACK   0x0000
  13. #define BLUE    0x001F
  14. #define RED     0xF800
  15. #define GREEN   0x07E0
  16. #define CYAN    0x07FF
  17. #define MAGENTA 0xF81F
  18. #define YELLOW  0xFFE0
  19. #define WHITE   0xFFFF
  20. //RGB顏色
  21. #define RGB(r,g,b) (((r&0xF8)<<8)|((g&0xFC)<<3)|(b>>3))
  22. #define GREY      RGB(127, 127, 127)
  23. #define DARKGREY  RGB(64, 64, 64)
  24. #define TURQUOISE RGB(0, 128, 128)
  25. #define PINK      RGB(255, 128, 192)
  26. #define OLIVE     RGB(128, 128, 0)
  27. #define PURPLE    RGB(128, 0, 128)
  28. #define AZURE     RGB(0, 128, 255)
  29. #define ORANGE    RGB(255,128,64)

  30. #define ch1     A5
  31. #define max_buf 321
  32. #define max     320
  33. #define _ms     150
  34. #define vatel   5

  35. int xpos, ypos;
  36. uint8_t PENRADIUS = 1;
  37. uint8_t Orientation = 1;    //屏幕旋轉(zhuǎn)
  38. int i,value;
  39. int time[]={0,7,20,46,102,224,460};
  40. int _adc,_us;
  41. int _id; //點擊的按鈕id
  42. int buf[max_buf];
  43. int buf_old[max];
  44. bool hold=false;
  45. long t;
  46. int delay_us=0;
  47. int Freq,Cycl,Duty,Pw,V_max,V_min,V_mid,Vpp;
  48. int i1,i2,i3;
  49. int Tv=209;  //觸發(fā)電壓
  50. String sj[]={" x1:1 "," x10:1 ","x100:1"};
  51. int mode=0;
  52. float _Vmax,_Vmin,_Vmid,_Vrms;
  53. int old_Freq,old_Duty;
  54. bool parameter=false;
  55. int adc_i=8;
  56. /*
  57. //主菜單
  58. void man_menu(void){
  59.   tft.fillScreen(BLACK);
  60.   tft.setTextSize(1);
  61.   tft.setTextColor(WHITE, BLACK);
  62.   tft.setCursor(60, 20);
  63.   tft.print("plase select menu");
  64.   
  65.   btn_osc.initButton(&tft,100,60,120,40,WHITE,CYAN,BLACK, "OSC",2);
  66.   btn_pwm.initButton(&tft,100,110,120,40,WHITE,CYAN,BLACK, "PWM",2);
  67.   btn_osc.drawButton(false);
  68.   btn_pwm.drawButton(false);
  69.   while (1) {
  70.     update_button_list(buttons);
  71.     if (btn_osc.justPressed()) {
  72.       btn_osc.drawButton(true);
  73.       osc();
  74.     }

  75.   }
  76. }*/

  77. void setup(void){
  78.   tft.reset();
  79.   tft.begin(0x5408);
  80.   tft.setRotation(Orientation);
  81.   osc();
  82. }

  83. void draw_btn(int x,int y,int w,int h,String lable){
  84.   tft.setTextColor(WHITE, BLUE);
  85.   tft.drawRoundRect(x, y, w, h, 3, RED);
  86.   tft.setCursor(x+3, y+9);
  87.   tft.print(lable);
  88. }

  89. //示波器
  90. void osc(void){
  91.   tft.fillScreen(BLACK);
  92.   tft.fillRect(0, 0, tft.width(), 30, BLUE);
  93.   tft.fillRect(0, 210, tft.width(), 30, BLUE);
  94.   tft.setTextSize(0);
  95.   
  96.   draw_btn(2,212,48,25," Auto");
  97.   draw_btn(55,212,48,25," x1:1 ");
  98.   draw_btn(108,212,48,25,"  D+");
  99.   draw_btn(162,212,48,25,"  D-");
  100.   draw_btn(217,212,48,25,"measure");
  101.   draw_btn(271,212,48,25," Hold");

  102.   while(1){
  103.     bool down =Touch_getXY();
  104.     if(down&&ypos<230&&ypos>200){
  105.       if(xpos>2&&xpos<48){          //Auto
  106.         _id=0;
  107.         
  108.         delay(100);
  109.       }else if(xpos>55&&xpos<103){   //衰減
  110.         _id=1;
  111.         mode++;
  112.         if(mode>2){mode=0;}
  113.         draw_btn(55,212,48,25,sj[mode]);
  114.       }else if(xpos>108&&xpos<157){  //D+
  115.         _id=2;
  116.         _us+=1;
  117.         if(_us>=6){_us=6;}
  118.       }else if(xpos>162&&xpos<210){  //D-
  119.         _id=3;
  120.         _us-=1;
  121.         if(_us<=0){_us=0;}
  122.       }else if(xpos>217&&xpos<266){  //測量
  123.         _id=4;
  124.         tft.fillRect(0, 0, tft.width(), 30, BLUE);
  125.         if(parameter){
  126.           parameter=false;
  127.         }else{
  128.           parameter=true;
  129.         }
  130.         //delay(100);
  131.       }else if(xpos>271&&xpos<320){  //hold
  132.         _id=5;
  133.         tft.setTextColor(WHITE, BLACK);
  134.         tft.setCursor(5, 40);
  135.         if(hold){
  136.           hold=false;
  137.           tft.print("    ");
  138.         }else{
  139.           hold=true;
  140.           tft.print("HOLD");
  141.         }
  142.         delay(100);
  143.       }
  144.     }else if(down&&ypos<200&&ypos>20){  //觸發(fā)電壓
  145.       tft.drawLine(0, Tv, 5, Tv, BLACK);
  146.       Tv=ypos+10;
  147.     }
  148.    
  149.     if(hold==false){
  150.         sampling();
  151.         measure();
  152.         display_cls();
  153.         display();
  154.     }
  155.   }
  156. }

  157. //獲取觸屏位置
  158. bool Touch_getXY(void){
  159.   tp = ts.getPoint();   //tp.x, tp.y的值從ADC讀取
  160.   pinMode(XM, OUTPUT);  //恢復(fù)共享引腳
  161.   pinMode(YP, OUTPUT);
  162.   bool pressed = (tp.z>MINPRESSURE && tp.z<MAXPRESSURE);
  163.   //模屏豎屏坐標(biāo)計算
  164.   if (pressed) {
  165.     switch (Orientation) {
  166.       case 0:
  167.         xpos = map(tp.x, TS_LEFT, TS_RT, 0, tft.width());
  168.         ypos = map(tp.y, TS_TOP, TS_BOT, 0, tft.height());
  169.         break;
  170.       case 1:
  171.         xpos = map(tp.y, TS_TOP, TS_BOT, 0, tft.width());
  172.         ypos = map(tp.x, TS_RT, TS_LEFT, 0, tft.height());
  173.         break;
  174.       case 2:
  175.         xpos = map(tp.x, TS_RT, TS_LEFT, 0, tft.width());
  176.         ypos = map(tp.y, TS_BOT, TS_TOP, 0, tft.height());
  177.         break;
  178.       case 3:
  179.         xpos = map(tp.y, TS_BOT, TS_TOP, 0, tft.width());
  180.         ypos = map(tp.y, TS_LEFT, TS_RT, 0, tft.height());
  181.         break;
  182.     }
  183.     /*
  184.     tft.setTextColor(WHITE,BLUE);
  185.     tft.setCursor(250, 10);
  186.     tft.print("x=" + String(xpos) + " y=" + String(ypos) + "   ");*/
  187.   }
  188.   return pressed;
  189. }

  190. void loop(){
  191.   
  192.   
  193. }


  194. //ADC采樣通道
  195. void ADC_pin(uint16_t pin){
  196.   switch(pin){
  197.     case A0: //A0
  198.       ADMUX =_BV(REFS0);break;
  199.     case A1: //A1
  200.       ADMUX =_BV(REFS0)|_BV(MUX0);break;
  201.     case A2: //A2
  202.       ADMUX =_BV(REFS0)|_BV(MUX1);break;
  203.     case A3: //A3
  204.       ADMUX =_BV(REFS0)|_BV(MUX0)|_BV(MUX1);break;
  205.     case A4: //A4
  206.       ADMUX =_BV(REFS0)|_BV(MUX2);break;
  207.     case A5: //A5
  208.       ADMUX =_BV(REFS0)|_BV(MUX0)|_BV(MUX2);break;
  209.     case A6: //A6
  210.       ADMUX =_BV(REFS0)|_BV(MUX1)|_BV(MUX2);break;
  211.     case A7: //A7
  212.       ADMUX=_BV(REFS0)|_BV(MUX0)|_BV(MUX1)|_BV(MUX2);
  213.       break;
  214.     default:
  215.       break;
  216.   }
  217.   //ADMUX |= (1<<REFS1)|(1<<REFS0);//內(nèi)部1.1V參考電壓
  218. }

  219. //ADC分頻,采樣速率
  220. void ADC_adcsra(int key) {
  221.   switch (key){
  222.     case 4://ADC Sample=16MHz/4/13=307.6KHz,實測142.8KHz
  223.       ADCSRA = _BV(ADPS1); //7us采樣一次
  224.       break;
  225.     case 8://ADC Sample=16MHz/8/13=153.8KHz,實測100KHz
  226.       ADCSRA = _BV(ADPS0)|_BV(ADPS1);  //10us采樣一次
  227.       break;
  228.     case 16://ADC Sample=16MHz/16/13=76.8KHz,實測58.8KHz
  229.       ADCSRA = _BV(ADPS2);  //17us采樣一次
  230.       break;
  231.     case 32://ADC Sample=16MHz/32/13= 38.4KHz,實測33.3KHz
  232.       ADCSRA = _BV(ADPS2)|_BV(ADPS0);  //30us采樣一次
  233.       break;
  234.     case 64://ADC Sample=16MHz/64/13= 19.2KHz,實測17.8KHz
  235.       ADCSRA = _BV(ADPS2)|_BV(ADPS1);  //56us采樣一次
  236.       break;
  237.     case 128://ADC Sample=16MHz/128/13=9600Hz,實測8928Hz
  238.       ADCSRA =_BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0);  //112us
  239.       break;
  240.     default:
  241.       break;
  242.   }
  243.   ADCSRA |= _BV(ADEN);
  244. }

  245. //獲取ADC采樣值
  246. int _analogRead(void){
  247.   bitClear(ADCSRA, ADIF);
  248.   ADCSRA |= _BV(ADSC);
  249.   loop_until_bit_is_set(ADCSRA, ADIF);
  250.   return ADC;
  251. }

  252. //采樣
  253. void sampling(){
  254.   ADC_pin(ch1);         //使用ch1采樣(觸摸屏?xí)?
  255.   ADC_adcsra(8);        //使用4分頻采樣
  256.   //切換通道后前10次采樣是錯的,不要
  257.   for(i=0;i<15;i++){_analogRead();}
  258.   t = micros();         //采樣開始時間
  259.   for(i=0;i<max_buf;i++){
  260.     buf[i]=_analogRead();
  261.     if(time[_us]>0){delayMicroseconds(time[_us]);}
  262.   }
  263.   t = (micros()-t)/max_buf; //采樣1次時間
  264.   ADC_adcsra(128);      //恢復(fù)128分頻給觸摸屏
  265. }

  266. //計算參數(shù)
  267. void measure(void){
  268.   V_max = buf[0];V_min = buf[0];
  269.   for(i=0;i<max;i++){
  270.     V_max = ((V_max<buf[i])?buf[i]:V_max);//最大值
  271.     V_min = ((V_min>buf[i])?buf[i]:V_min);//最小值
  272.   }
  273.   V_mid = (V_max+V_min)/2; //平均值
  274.   Vpp   = (V_max-V_min);   //峰峰值
  275.   int H=map(Tv,30,210,1023,0);//觸發(fā)值
  276.   
  277.   if(Vpp==V_max&&V_mid*2==Vpp){ //方波
  278.     //周期開始點
  279.     for (i=0; i<max;i++){
  280.       if(buf[i]<V_mid&&buf[i+1]>V_mid)
  281.         {i1=i;break;}
  282.       }
  283.     for(i=i1+1;i<max;i++){
  284.       //周期內(nèi)高電平結(jié)束點
  285.       if(buf[i]>V_mid&&buf[i+1]<V_mid){i2=i;}
  286.       //周期結(jié)束點
  287.       if(buf[i]<V_mid&&buf[i+1]>V_mid)
  288.         {i3=i;break;}
  289.     }
  290.     Cycl=(i3-i1);  //周期時間=周期結(jié)速點-周期開始點
  291.     Pw=(i2-i1);     //低電平時間
  292.    
  293.     Duty =(Pw*100)/Cycl; //占空比=低電平時間/周期時間
  294.     Freq =1000000/Cycl/t; //頻率
  295.     if(Vpp<H){
  296.       Cycl=0;Pw=0;Duty=0;Freq=0;
  297.     }else if(Freq<0){Freq=old_Freq;Duty=old_Duty;}
  298.   }
  299.   
  300. }

  301. //顯示
  302. void display(void){
  303.   for(i=0;i<max+1;i++){
  304.     buf[i]=map(buf[i],0,1023,209,31);     //計算坐標(biāo)
  305.   }
  306.   for(i=0;i<max;i++){
  307.     tft.drawLine(i, buf[i], i, buf[i+1], WHITE);
  308.     buf_old[i]=buf[i];
  309.   }
  310.   display_v();
  311.   old_Freq=Freq;
  312.   old_Duty=Duty;
  313. }

  314. void display_v(void){
  315.   int a=0;
  316.   tft.setTextColor(WHITE,BLUE);
  317.   if(parameter){
  318.    
  319.     //衰減倍數(shù)
  320.     if(mode==0){
  321.       a=1;
  322.     }else if(mode==1){
  323.       a=10;
  324.     }else if(mode==2){
  325.       a=100;
  326.     }
  327.     _Vmax=V_max*vatel/1023;
  328.     _Vmin=V_min*vatel/1023;
  329.     _Vmid=V_mid*vatel/1023;
  330.     _Vrms=Vpp*vatel/1023;
  331.   
  332.     tft.setCursor(2, 5);
  333.     tft.print("Freq:");
  334.     tft.print(Freq);
  335.     tft.print("Hz     ");
  336.     tft.setCursor(2, 20);
  337.     tft.print("Cycl:");
  338.     tft.print(Cycl*t);
  339.     tft.print("us    ");
  340.     tft.setCursor(85, 5);
  341.     tft.print("Pw:");
  342.     tft.print(Pw*t);
  343.     tft.print("us  ");
  344.     tft.setCursor(85, 20);
  345.     tft.print("Duty:");
  346.     tft.print(Duty);
  347.     tft.print("%   ");
  348.   
  349.     tft.setCursor(155, 5);
  350.     tft.print("Vmax:");
  351.     tft.print(_Vmax*a);
  352.     tft.print("V   ");
  353.     tft.setCursor(155, 20);
  354.     tft.print("Vmin:");
  355.     tft.print(_Vmin*a);
  356.     tft.print("V   ");
  357.     tft.setCursor(235, 5);
  358.     tft.print("Vmid:");
  359.     tft.print(_Vmid*a);
  360.     tft.print("V  ");
  361.     tft.setCursor(235, 20);
  362.     tft.print("Vrms:");
  363.     tft.print(_Vrms*a);
  364.     tft.print("V  ");
  365.   }else{
  366.     tft.setTextColor(WHITE,BLUE);
  367.     tft.setCursor(5, 14);
  368.     tft.print("Arduino Digital OSC V2.0");
  369.     tft.setCursor(250, 20);
  370.     tft.print("Delay:"+String(time[_us]) +"us  ");
  371.   }
  372. }


  373. //清除
  374. void display_cls(void){
  375.   for(i=0;i<max;i++){
  376.     tft.drawLine(i, buf_old[i], i, buf_old[i+1], BLACK);
  377.   }
  378.   
  379.   //繪網(wǎng)格
  380.   for(i=32;i<=320;i+=32){  //豎線
  381.     tft.drawLine(i, 30, i, 210, DARKGREY);
  382.   }
  383.   for(i=60;i<=180;i+=30){ //橫線
  384.     tft.drawLine(0, i, 320, i, DARKGREY);
  385.   }
  386.   tft.drawLine(0, 120, 320, 120, RED);
  387.   tft.drawLine(160, 30, 160, 210, RED);
  388.   //觸發(fā)電壓
  389.   tft.drawLine(0, Tv, 3, Tv, YELLOW);
  390.   
  391. }
復(fù)制代碼


作者: 菜雞一只314159    時間: 2019-4-28 12:26
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <TouchScreen.h>
請問這幾個頭文件呢
作者: 菜雞一只314159    時間: 2019-4-28 12:28
哪里可以導(dǎo)入這些庫
作者: godmain    時間: 2019-6-23 05:43
納秒級的信號能采集嗎
作者: zmfc12    時間: 2019-6-23 10:07
牛人呀
作者: lgf2974    時間: 2019-10-26 10:10
頭文件不給,什么arduino單片機不說,單片機怎么接線不說,這程序啥用呢?
作者: 完完全全    時間: 2019-10-30 09:45
發(fā)現(xiàn)伸手黨挺多的
作者: lqb7733    時間: 2020-3-5 09:58
謝謝分享
作者: 1679079206    時間: 2020-3-13 13:00
lgf2974 發(fā)表于 2019-10-26 10:10
頭文件不給,什么arduino單片機不說,單片機怎么接線不說,這程序啥用呢?

Arduino ide 不用頭文件
作者: TZHXKD    時間: 2020-3-17 21:25
1679079206 發(fā)表于 2020-3-13 13:00
Arduino ide 不用頭文件

啥庫
作者: 大牛先生    時間: 2020-3-18 10:21
用的什么顯示屏?
作者: 氮磷鉀x    時間: 2020-4-4 12:27
下載后一直白屏是怎么回事
作者: cy007    時間: 2020-4-10 21:22
謝謝樓主的分享,下載了學(xué)習(xí)一下
作者: booooy    時間: 2020-4-14 11:41
剛好手里有塊2.4寸屏  來試試
作者: zxy2266    時間: 2020-4-15 15:02
我也一直沒點亮這鳥屏,買了好多年了,手里好多屏都點亮了,我試試你這驅(qū)動可以不
作者: jemery1030    時間: 2020-9-29 19:06
測試非常城功,太好了,幫助很大。
作者: smartphone    時間: 2020-10-29 21:09
好東西必須下載仿制
作者: smartphone    時間: 2020-10-29 21:22
編譯不過 'A1' was not declared in this scope

作者: carlson-chuo    時間: 2020-11-14 16:59
樓主強啊,下再來學(xué)習(xí),謝謝。
作者: zxy2266    時間: 2020-12-9 16:42
屏驅(qū)動IC 啥、

作者: zxy2266    時間: 2020-12-9 17:05
#在這里快速回復(fù)#<TouchScreen.h>沒找到,能否提供下鏈接
作者: zxy2266    時間: 2020-12-9 17:14
搞定了,謝謝,這屏折騰了我好幾年
作者: ccjxhl    時間: 2021-1-8 22:53
mcufriend的這個tft屏很難搞啊,正在學(xué)子
作者: ccjxhl    時間: 2021-1-8 22:54
網(wǎng)上關(guān)于這個屏的資料太少了,而且看著樣子一樣,采用的芯片不一樣,很多山寨貨。
作者: 13758045498    時間: 2021-1-31 16:12
arduino uno  屏幕是2。4寸tft
作者: zh68a11    時間: 2021-2-28 14:17
下來學(xué)習(xí)一下,謝謝。
作者: lucq7896    時間: 2021-3-25 21:04
有做出來的嗎?  就是白屏, 不知道是什么原因,小白不懂怎么弄了。求救啊
作者: lucq7896    時間: 2021-3-25 21:07
這個屏好像是直接插在開發(fā)板上的

作者: arduino0630    時間: 2022-1-15 16:13
請問如何觸控部分如何改成3.5寸的?手上2.4寸壞了,只有3.5寸的
作者: arduino0630    時間: 2022-1-16 11:30
lucq7896 發(fā)表于 2021-3-25 21:04
有做出來的嗎?  就是白屏, 不知道是什么原因,小白不懂怎么弄了。求救啊

可以改下tft.begin()的id
作者: arduino0630    時間: 2022-2-1 11:37
Arduino示波器資料.zip (1.24 MB, 下載次數(shù): 72)
整理了一下資料
有代碼、原理圖和庫

作者: lfq3779    時間: 2022-3-27 15:15
今天試了一下1.0的程序可以顯示但閃動很大,2.0的程序燒錄后顯示屏只有背光燈亮白屏無顯示��!
作者: hack906447    時間: 2022-4-29 05:54
請問是否有寬帶速度規(guī)格等方便參考
作者: mick32    時間: 2022-4-30 02:44
MCUFRIEND_kbv
www.arduino.cc/reference/en/libraries/mcufriend_kbv/
github.com/prenticedavid/MCUFRIEND_kbv
github.com/adafruit/Adafruit-GFX-Library
github.com/adafruit/Adafruit_TouchScreen/blob/master/TouchScreen.h


作者: hack906447    時間: 2022-5-1 20:32
是不是不能量測負(fù)電壓與AC電壓?
作者: x735wc5dv6qs5x    時間: 2022-5-14 21:20
我試過,什么效果都沒有,就只有白屏
作者: x735wc5dv6qs5x    時間: 2022-5-14 21:22
我剛剛試過這個程序,只有白屏沒有任何圖像,小白求救
作者: hack906447    時間: 2022-7-1 21:01
x735wc5dv6qs5x 發(fā)表于 2022-5-14 21:22
我剛剛試過這個程序,只有白屏沒有任何圖像,小白求救

改內(nèi)容ID
作者: yang1234564445    時間: 2023-4-22 16:32
arduino0630 發(fā)表于 2022-2-1 11:37
整理了一下資料
有代碼、原理圖和庫

OK
謝謝樓主哦
作者: xxjs120    時間: 2024-5-6 12:18
原件都有,等下試一下,謝謝分享

作者: luly8818    時間: 2024-10-17 18:45

謝謝分享,原件都有,等下試一下,謝謝分享




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1