Пультоскоп на Arduino 27МГц!!!

Novice User
Offline
Зарегистрирован: 25.09.2017

 D5- для частотомера

C3-аналоговый вход для пультоскопа

 

BuonanotteMasha
BuonanotteMasha аватар
Offline
Зарегистрирован: 02.01.2018

Novice User пишет:

 D5- для частотомера

C3-аналоговый вход для пультоскопа

 

Спасибо за оперативный ответ. 

Замечу, что на сайте http://srukami.inf.ua/pultoscop_v25110.html в схеме либо коде есть неточности

#define power 8 //пин который опрашивает кнопку включения
#define OFF 14//пин который управляет ключем питания
#define  timepowerON 50 //время удержания кнопки выключения
#define levo 13  //кнопка ЛЕВО(можно любой пин)
#define ok 12    //кнопка ОК(можно любой пин)
#define pravo 11 //кнопка ПРАВО(можно любой пин)
#define akb A5 //любой своюодный аналоговый пин для измерения напряжения АКБ 

Конкретно D8(пин который опрашивает кнопку включения) на схеме не показан

void setup(){
pinMode(A4,INPUT);
digitalWrite(OFF,HIGH);//включем питание 

В функции setup() А4 настроен на вход. Возможно речь о А5 (АКБ)

Код взят с сайта

Да и настроек пинов кнопок тоже не заметил

Novice User
Offline
Зарегистрирован: 25.09.2017

а зачем А5 настраивать на вход?

Novice User
Offline
Зарегистрирован: 25.09.2017

MIK22 пишет:

Я пробовал пультоскоп на Massduino UNO LC c тактовой частотой 16 Ьгц.

Получил,можно ваш скетч?

Electronik83
Offline
Зарегистрирован: 06.12.2015

mobistrike пишет:

Electronik83 пишет:

Работоспособна схема при питании ардуины строго +5 вольт. ....

Тут теряется весь смысл измерения напряжения питания arduino .

Я пошел другим путем - взял за основу код от форумчанина DIMAX, за что ему спасибо  - ТУТ . 

Измерение производится внутренней коммутацией, не используя внешние аналоговые входы, причем довольно точно.

Заинтересовало, только так и не смог ничего измерить. В порт выводит inf

..... ((((((

MIK22
Offline
Зарегистрирован: 09.02.2017
Скутч не мой, сборный.
#include <SPI.h>
#include <MsTimer2.h>
#include <FreqMeasure.h>
#include <Adafruit_ST7735.h>
#include <PWM.h> 
#include <avr/wdt.h> 
 
#define TFT_CS  10
#define TFT_DC  7
#define TFT_RST A0
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);
#define TFT_SCLK 13 // set these to be whatever pins you like!
#define TFT_MOSI 11  // set these to be whatever pins you like!
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
 
#define MEASURE_PERIOD 500  // время периода измерения
#define ADC_U_COEFF 0.000008408 // коэффициент перевода кода АЦП в напряжение
int timeCount;  // счетчик времени
long  sumU1; // переменные для суммирования кодов АЦП
long  avarageU1; // сумма кодов АЦП (среднее значение * 500)
boolean flagReady;  // признак готовности данных измерения
#define TEAL    0x0410
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define BUFSIZE 700
#define Reset_AVR() wdt_enable(WDTO_30MS); while(1) {}            // soft reset
#define overclock 16.0
#define KEY_L 2  // кнопка ЛЕВО(можно любой пин)
#define KEY_OK 3 // кнопка ОК(можно любой пин)
#define KEY_R 4  // кнопка ПРАВО(можно любой пин)
#define Out  9   //пин для генератора сигналов (не менять)
#define led  9   //пин для генератора dds (не менять)
//пользовательские настройки!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
byte menu=0;     // пункт меню
byte mainMenu=0; // пункт главного меню
byte subMenu=0;     // пункт меню 
byte SinU=30;   //уровень синхронизации 0 до 255 
byte adcBuf[701]; // буфер проебразований АЦП
byte synU=30;    // уровень синхронизации 0 до 255
byte razv=0;//значение развертки
bool vRef=1;  // флаг опорного напряжения
bool pause=0; //флаг режима паузы
int Vmax=0;// максимальное напряжение 
int PWM = 50;    // стартовое значение ШИМ от 0 до 100 для генератора    
int  pOffset=0;   // смещение графика в режиме паузы (прокрутка)
int grOffset=0; // смещение графика в рабочем режиме
float Vakb=0; //напряженеиЕКБ
float VCC=4.16;
float frequency = 500; //стартовое значение частоты в Гц
int d=0;
byte hag=0;
int mnog=0;
boolean flag=0;
double sum=0;
unsigned long count =0; 
//##############################################
  static float vccRead(byte us =100) {
  ADMUX = (1<<REFS0)|(1<<MUX0); // опорное напряжение - Vcc   
  ADMUX |= 0xC0;  //стабилизированного напряжения 1.0
  delayMicroseconds(us); 
  ADCSRA = 0xC7;
  //ADCSRA |= (1<<ADSC);         // запуск АЦ-преобразования
  while(ADCSRA & (1<<ADSC)); // и ожидание его завершения
  word x = ADC;
  return x ? (1100L * 4095) / x : -1;  }   
 
  /*int Vbg() {  
ADMUX = (1<<REFS0)|(0<<REFS1)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(1<<MUX0);
long buffersamp=0;
for (int n=0x0; n<=0xff; n++ ) {
ADCSRA |= (1<<ADSC)|(1<<ADEN);  //Starts a new conversion
while (bit_is_set(ADCSRA,ADSC));
buffersamp += ADC; }
buffersamp >>=4; //16368 full scale 14bit
ADCSRA &= ~(1 << ADEN);  // отключаем АЦП
return buffersamp;
 }*/
//#########################  главное меню  ##########################
void GlavMenu (){
     tft.setRotation(1);
     tft.setTextColor(RED);
     tft.setCursor(35, 13);
     tft.println("Осцилограф");
     tft.setCursor(35, 28);
     tft.println("Генератор PWM");
     tft.setCursor(35, 43);
     tft.println("Снятие АЧХ");  
     tft.setCursor(35, 58);
     tft.println("Терминал"); 
     tft.setCursor(35, 73); 
     tft.println("Частотомер");  
     tft.setCursor(35, 88);  
     tft.println("Вольтметр");      
     tft.setTextColor(BLUE);     
     tft.setCursor(35, 103);
     tft.println("Батарея ="); tft.println(Vakb); tft.print("B");            
}
void setup(){ 
    Vakb= vccRead()/4000,1;    
   //Vakb= (float)(1.0*16368)/Vbg() ;
   //pinMode(analogRead_12bits(A3),INPUT); 
   pinMode(analogRead(A3),INPUT);
   pinMode(8, INPUT);
   pinMode(KEY_OK, INPUT); pinMode(KEY_L, INPUT); pinMode(KEY_R, INPUT);  //  тест!!! Так меньше будет потребление питания и так правильнее!!!!
   tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab    
   tft.setRotation(1);              //  повернуть по горизонту
   tft.fillScreen(BLACK);
   
   tft.drawRect(0,0,160,128,WHITE); // рисуем рамку
   tft.drawRect(3,3,154,122,BLUE); // рисуем рамку
   tft.drawRect(6,6,148,116,RED); // рисуем рамку 
   
 while(digitalRead(KEY_OK) == LOW) {  // зацикливаем, пока не нажали кнопку ОК из главного меню (перебор меню)
   if (digitalRead(KEY_L) == HIGH) { mainMenu--; if (mainMenu==255) mainMenu = 5; delay (100); }
   if (digitalRead(KEY_R) == HIGH) { mainMenu++; if (mainMenu==6  ) mainMenu = 0; delay (100); }
    // Рисуем главное меню  
    if (mainMenu==0) {     
       GlavMenu ();
     tft.setCursor(35, 13);  tft.println("Осцилограф"); }
    if (mainMenu==1) {
       GlavMenu ();
     tft.setCursor(35, 28);  tft.println("Генератор PWM"); }        
    if (mainMenu==2) {
       GlavMenu ();
     tft.setCursor(35, 43);  tft.print("Снятие АЧХ"); } 
    if (mainMenu==3) {
       GlavMenu ();
     tft.setCursor(35, 58);  tft.print("Терминал"); }    
    if (mainMenu==4) {
       GlavMenu ();
     tft.setCursor(35, 73);  tft.print("Частотомер"); }    
    if (mainMenu==5) {
       GlavMenu ();
     tft.setCursor(35, 88);  tft.print("Вольтметр"); } 
 
    if (digitalRead(KEY_L) == HIGH && digitalRead(KEY_R) == HIGH) { delay(1000);
    wdt_enable(WDTO_30MS); while(1) {} ;
    Reset_AVR(); } // soft reset             
  
   if (mainMenu==0) { FreqMeasure.begin(); }
   if (mainMenu==1) { InitTimersSafe(); bool success = SetPinFrequencySafe(led, frequency); }   
   if (mainMenu==2) razv = 0; 
   if (mainMenu==4) { FreqMeasure.begin(); }    
    delay(100); // антидребезг кнопки ОК   
 }
 }
//###############################################################
void Zamer() {
  if (razv%10) { // (razv>0)        // если развертка без задержек всяких
    ADCSRA = 0b11100000 | (8-(razv%10)); // установили делитель (/2 - не работает, так что начинаем с /4)
    for(int i=0; i<BUFSIZE; i++) {  // цикл для чтения  
      //while ((ADCSRA & 0x10)==0);   // ждем готовность АЦП
      //ADCSRA|=0x10;                 // запускаем следующее преобразование
      while(ADCSRA & (1<<ADSC)); // и ожидание его завершения
      ADCSRA |= 1<<ADSC;
      adcBuf[i]=ADCH;               // записываем данные в массив
    }
    delay(0.3*BUFSIZE);             // компенсация задержки по сравнению с разверткой 0...
  } else {                          // развертка с задержками (delay)
    ADCSRA = 0b11100111;            // делитель на /128
    for(int i=0; i<BUFSIZE; i++) {  // цикл для чтения
      //while ((ADCSRA & 0x10)==0);   // ждем готовность АЦП
      //ADCSRA|=0x10;                 // запускаем следующее преобразование
      while(ADCSRA & (1<<ADSC)); // и ожидание его завершения
      ADCSRA |= 1<<ADSC;
      delayMicroseconds(500);       // делаем задержку
      adcBuf[i]=ADCH;               // записываем данные в массив
    }
  }
}
//###################################################################
// обработка прерывания 1 мс
void  timerInterupt() {
  timeCount++;  // +1 счетчик выборок усреднения
  sumU1+= analogRead(A4);  // суммирование кодов АЦП
  // проверка числа выборок усреднения
  if ( timeCount >= MEASURE_PERIOD ) {
    timeCount= 0;
    avarageU1= sumU1; // перегрузка среднего значения     
    sumU1= 0;    
    flagReady= true;  // признак результат измерений готов
    }
}              
//##################################################################
void loop() { 
  //float Vakb= (float)(1.0*16368)/Vbg() ;
  if(mainMenu==0){tft.fillScreen(BLACK);
  while(1){ 
  ADMUX = vRef ? 0b00100011 : 0b11100011; // установка опорного напряжения АЦП        
  //ADMUX = vRef ? 0b11100100 : 0b10100100 : 0b00100100; // установка опорного напряжения АЦП     
  if (!pause) Zamer(); // если нет паузы, то снимаем осциллограмму  
   // обрабатываем кнопки
  if (digitalRead(KEY_L))   switch (subMenu) {
    case 0 : tft.setRotation(0); tft.fillRect(15, 0, 106, 24, BLACK);   tft.fillRect(16, 34, 100 , 160, BLACK); tft.setRotation(1);vRef=!vRef;  break;
    case 1 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); razv--; if(razv==255) razv= 0; break;
    case 2 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); pOffset-=10; if (pOffset<0) pOffset=0; break;
    case 3 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1);synU-=20; if (synU<20) synU=20;        break;
  }
  if (digitalRead(KEY_R))  switch (subMenu) {
    case 0 : tft.setRotation(0); tft.fillRect(15, 0, 106, 24, BLACK); tft.fillRect(16, 34, 100 , 160, BLACK); tft.setRotation(1); vRef=!vRef;  break;
    case 1 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); razv++; if (razv==7) razv=6;           break;
    case 2 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); pOffset+=10; if(pOffset>570) pOffset=570; break;
    case 3 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); synU+=20; if(synU>230) synU=230;       break;
  }       
  if (digitalRead(KEY_OK)) { { subMenu++; if (subMenu==4) {subMenu=0; pause=0; } } // перебор меню
  delay (100);
  tft.setRotation(0); 
  tft.fillRect(118, 0, 128, 160, BLACK); //стирание верх меню
  tft.fillRect( 0, 0, 10, 160, BLACK);//стиране ниж меню    
  tft.fillRect(16, 34, 100, 160, BLACK);//стиране поля графика
  }  
   // === Отрисовка меню осцилла ===      
  tft.setRotation(1); 
  if (subMenu==0) tft.setTextColor(WHITE, RED); else tft.setTextColor(RED);tft.setCursor(4,0); 
  if (vRef) { tft.print("V=5.3");} else tft.print("V=1.1");
  if (subMenu==1) tft.setTextColor(WHITE, RED); else tft.setTextColor(RED);
  tft.setCursor(58, 0); tft.print("РАЗВ=");  tft.print(razv);
  if (subMenu==2) { tft.setTextColor(WHITE, RED); pause=1; } else tft.setTextColor(RED);
  tft.setCursor(120,0); tft.print("ПАУЗА");  
  if (subMenu==3) { pOffset=0; pause=0; 
  tft.fillCircle(155, 112-synU/3.5, 5, WHITE);  tft.fillCircle(155, 112-synU/3.5, 2, BLUE);}
    
 if(FreqMeasure.available()) {     
  sum = sum + FreqMeasure.read();
  count = count + 1;    if (count > 30) {
  float frequency = FreqMeasure.countToFrequency(sum / count);    
  tft.fillRect( 0, 121, 130, 128, BLACK);   
  tft.setTextColor(TEAL); tft.setCursor(0, 121); tft.println("F="); tft.setCursor(13, 121);
  //--------Блок вычисления частоты в ГЦ---------------------
  if (frequency <= 1000){   tft.print(frequency);  tft.println("Hz");       }
  //--------Блок вычисления частоты в КГЦ---------------------      
  else { float freq = frequency / 1000;  tft.print(freq);  tft.println("KHz");  }        
  sum = 0;  count = 0;   
    }
  }   
    tft.setTextColor(TEAL);
     tft.print("v");
    tft.setCursor(135,121);
    tft.print(Vakb);    
    tft.setCursor(69,121);
    tft.print("Vmax=");
    tft.setTextColor(TEAL, BLACK);
    if (vRef) tft.print(Vmax*VCC/255,1);
        else  tft.print(Vmax*1.1/255,1);
    delay(200);
 
if (vRef) {
    tft.setTextColor(TEAL);
    tft.setCursor(18,104);tft.println("0"); 
    tft.setCursor(0, 88); tft.println("1.00"); 
    tft.setCursor(0, 72); tft.println("2.00"); 
    tft.setCursor(0, 56); tft.println("3.00"); 
    tft.setCursor(0, 40); tft.println("4.00"); 
    tft.setCursor(0, 24); tft.println("5.00");        
}
else  {
    tft.setTextColor(TEAL);
    tft.setCursor(18,104);tft.println("0"); 
    tft.setCursor(0, 88); tft.println("0.25"); 
    tft.setCursor(0, 72); tft.println("0.50"); 
    tft.setCursor(0, 56); tft.println("0.75"); 
    tft.setCursor(0, 40); tft.println("1.00"); 
    tft.setCursor(0, 24); tft.println("1.25");        
}
 //ось напряжения##########################################  
 tft.drawFastVLine(32,12,102,BLUE);tft.drawFastVLine(33,12,102,BLUE);   
 for(byte i=110;i>14; i=i-16) {tft.drawLine( 28, i,32 , i, BLUE); } // черточки слева 
 
 //ось времени##########################################
 tft.drawFastHLine(33,112,160,RED);tft.drawFastHLine(33,113,160,RED);
 for(byte i=160;i>34; i=i-16) {tft.drawLine( i, 113, i, 117, RED); } // черточки внизу
 
 // Определение точки синхронизации 
  bool flagSINHRO=0;
  bool flagSINHRnull=0;
  for (int y=1; y<573; y++) {
    if (!flagSINHRO && adcBuf[y]<SinU) flagSINHRnull=1;
    if (!flagSINHRO && flagSINHRnull && adcBuf[y]>SinU) { flagSINHRO=1; grOffset=y;  }  }   
 
  // максимальное значение сигнала
  Vmax=0; 
  for (int y=1; y<255; y++) if (Vmax<adcBuf[y]) Vmax=adcBuf[y];
// отрисовка графика
 
   for(int y=34; y<160; y++) {
   tft.drawLine(y, 110-adcBuf[y+(pause ? pOffset : grOffset)]/3.8, y, 110-adcBuf[y+(pause ? pOffset : grOffset)+1]/3.8,   (BLACK, GREEN));
   //tft.drawLine(y, 110-adcBuf[y+(pause ? pOffset : grOffset)]/3.8, y, 110-adcBuf[y+(pause ? pOffset : grOffset)+1]/3.8,   GREEN); 
   }     
    if(pause) { // если в режиме паузы, то рисуем с прокруткой...  
    tft.drawLine(pOffset/8,117,pOffset/8+6,117, BLUE); //шкала прокрутки
    tft.drawLine(pOffset/8,118,pOffset/8+6,118, BLUE); //шкала прокрутки      
     } else {
    tft.fillCircle(155,112-synU/3.8, 2, YELLOW); // рисуем уровень синхронизации    
    grOffset = 0;                               // сброс синхронизации
  }    
  if (digitalRead(KEY_L) == HIGH && digitalRead(KEY_R) == HIGH) { delay(1000);
  wdt_enable(WDTO_30MS); while(1) {} ;
  Reset_AVR(); } // soft reset 
  }
  }
  //######## Генератор ##############
if(mainMenu==1){ tft.fillScreen(BLACK);
  while(1){     
    tft.setRotation(1); 
  if (flag==0){//флаг выборов режима настройки  Частоты
  if(digitalRead(KEY_L)==HIGH){ frequency=frequency-mnog; if(frequency<0){ frequency=0; }
          bool success = SetPinFrequencySafe(Out, frequency);
          delay(3);//защита от дребезга
          tft.fillRect(6, 22, 160, 38, BLACK);//стирание поля
        }
   if(digitalRead(KEY_R)==HIGH){ frequency=frequency+mnog; 
          bool success = SetPinFrequencySafe(Out, frequency);
          delay(3);//защита от дребезга
          tft.fillRect(6, 22, 160, 38, BLACK);//стирание поля закрашиваем
        }
      }
   if(digitalRead(KEY_OK)==HIGH){//переключение разряда выбора частоты
        delay (30);
        while((digitalRead(KEY_OK)==HIGH)); hag++; if(hag>=6){ hag=0; }
        tft.fillRect(6, 5, 155, 22, BLACK);//стирание поля
        tft.fillRect(28, 109, 129, 127, BLACK);//стирание в низу число шим
      }
      ////////////////////////////////////////////////////////////////////
      tft.setCursor(36, 110); 
      tft.setTextColor(GREEN, BLACK);
      tft.setTextSize(2);
      tft.println("PWM=");
      tft.setCursor(84, 110);  
      tft.print(PWM);         
      tft.setCursor(108, 110);
      tft.println( "%");
      
      for (char x=22; x<126; ) {
    if (PWM!=0)             tft.drawLine(x, 60, x+PWM/6, 60, TEAL); x+=PWM/6;       // верх 
    if (PWM!=0 && PWM!=100) tft.drawLine(x, 60, x, 100, TEAL);                       // спад
    if (PWM!=100)           tft.drawLine(x, 100, x+15-PWM/6, 100, TEAL); x+=15-PWM/6; // низ
    if (PWM!=0 && PWM!=100 && x<120) tft.drawLine( x,100, x, 60, TEAL);              // подъем   
  }        
      //////////////////////////////////////////////////////////////////////
       tft.setTextSize(2);
       tft.setTextColor(WHITE);
       tft.setCursor(36, 30);
      long frequencyX=frequency*(overclock/16.0);
if(frequencyX<1000){tft.print(frequencyX); tft.println("Hz");}
if(frequencyX>=1000){if(frequencyX<10000){tft.print((frequencyX/1000.0),2);tft.println("KHz");}}
if(frequencyX>=10000){if(frequencyX<100000){tft.print((frequencyX/1000.0),1); tft.println("KHz");}}
if(frequencyX>=100000){tft.print((frequencyX/1000.0),0); tft.println("KHz");}  
 
  tft.setCursor(22, 5);
  tft.setTextColor(WHITE, BLUE);
  tft.println("X"); 
  tft.setTextColor(YELLOW);
if (hag==0) { // выбор множителя частоты 
  tft.print(1*(overclock/16.0),0);  tft.println("Hz");   
    mnog=1; flag=0;
  }
  // Выбор множителя частоты
  if (hag==1) { tft.print(  10*(overclock/16.0),0);  mnog=10; tft.println("Hz");  }
  if (hag==2) { tft.print( 100*(overclock/16.0),0);  mnog=100; tft.println("Hz"); }
  if (hag==3) { tft.print(1000*(overclock/16.0),0);  mnog=1000; tft.println("Hz");} 
  if (hag==4) { tft.print(10000*(overclock/16.0),0);  mnog=10000; tft.println("Hz");}
        
  if(hag==5){//выбор  PWM        
  flag=1;        
        tft.println("PWM=");       
        tft.setCursor(84, 5); 
        tft.print(PWM);         
        tft.setCursor(108, 5);        
        tft.println("%");
        
   if(digitalRead(KEY_R)) { tft.fillRect(20, 60, 130, 106, BLACK); tft.fillRect(6, 5, 155, 21, BLACK); 
 { PWM++; if(PWM>100) PWM=0; delay(200); }  }    
   if(digitalRead(KEY_L)) { tft.fillRect(20, 60, 130, 106, BLACK) ; tft.fillRect(6, 5, 155, 21, BLACK);
 { PWM--; if(PWM<0) PWM=100; delay(200); }  }         
      }   
      pwmWrite(Out, PWM*2.55); // задали ШИМ         
      delay(50);  
  if (digitalRead(KEY_L) == HIGH && digitalRead(KEY_R) == HIGH) { delay(1000);
  wdt_enable(WDTO_30MS); while(1) {} ;
  Reset_AVR(); } // soft reset           
  }
  } 
//############# Снятие ФЧХ #################
  if(mainMenu==2) {  tft.fillScreen(BLACK);   
  while(1){   
  ADMUX = vRef ? 0b01100011 : 0b11100011; // установка опорного напряжения АЦП    
  ADCSRA = 0b11100011; //delitel 8
  //ADCSRA|=0x10; // запуск преобразования АЦП
  ADCSRA |= 1<<ADSC;
 if (digitalRead(KEY_L))   switch (subMenu) {
    case 0 : tft.setRotation(0); tft.fillRect(15, 0, 106, 24, BLACK);   tft.fillRect(16, 34, 100 , 160, BLACK); tft.setRotation(1);vRef=!vRef;  break;
    case 1 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); razv--; if(razv==255) razv= 2; break;
    case 2 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); grOffset-=10; if (grOffset<0) grOffset=700; break;
    case 3 : for (int y=0; y<700; y++) adcBuf[y] = 0; grOffset=0; 
    tft.fillScreen(BLACK); tft.setCursor(3, 20); tft.print("Буфер очищен!"); delay(1000);  break; 
           } delay(100); // антидребезг кнопки
 
  if (digitalRead(KEY_R))  switch (subMenu) {
    case 0 : tft.setRotation(0); tft.fillRect(15, 0, 106, 24, BLACK); tft.fillRect(16, 34, 100 , 160, BLACK); tft.setRotation(1); vRef=!vRef;  break;
    case 1 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); razv++; if (razv==3) razv=0;           break;
    case 2 : tft.setRotation(0); tft.fillRect(16, 34, 100, 160, BLACK); tft.setRotation(1); grOffset+=10; if(grOffset>1402) grOffset=0; break;
           delay(100); } // антидребезг кнопки
  if (digitalRead(KEY_OK)) { { subMenu++; if (subMenu==4) {subMenu=0; pause=0; }  // перебор меню  
   adcBuf[(count++)%701] = 255; adcBuf[(count++)%701] = 0; adcBuf[(count++)%701] = 255; if (count>159) grOffset = count - 160; } // отметка паузы на графике
    delay(100);    // антидребезг кнопки    
  tft.setRotation(0); 
  tft.fillRect(118, 0, 128, 160, BLACK); //стирание верх меню
  tft.fillRect( 0, 0, 10, 160, BLACK);//стиране ниж меню    
  tft.fillRect(16, 34, 100, 160, BLACK);//стиране поля графика 
  }    
  // === Отрисовка менюшки ===  
  tft.setRotation(1);
 // tft.setTextColor(RED);  
  if (subMenu==0) tft.setTextColor(WHITE, RED); else tft.setTextColor(RED);tft.setCursor(4,0); 
  if (vRef) { tft.print("V=5.3");} else tft.print("V=1.1");
  if (subMenu==1)  tft.setTextColor(WHITE, RED); else tft.setTextColor(RED);
  tft.setCursor(58, 0); tft.print("РАЗВ=");  tft.print(razv);
  if (subMenu==2) { tft.setTextColor(WHITE, RED); pause=1; } else  tft.setTextColor(RED);
  tft.setCursor(120,0); tft.print("П "); tft.print(" ");  tft.print((grOffset%701)/3, 0);  tft.print("%"); 
  tft.setTextColor( RED);
  if (subMenu==3) {tft.setTextColor( RED); tft.setCursor(120,0); tft.print("C "); } 
 
  // максимальное значение сигнала
  Vmax=0; 
  for (int y=1; y<255; y++) if (Vmax<adcBuf[y]) Vmax=adcBuf[y];
  
  // === Отрисовка сетки ===  
    tft.setTextColor(TEAL);
    tft.print("v");
    tft.setCursor(135,121);
    tft.print(Vakb);     
    tft.setCursor(69,121);
    tft.print("Vmax=");
    tft.setTextColor(TEAL, BLACK);
    if (vRef) tft.print(Vmax*VCC/255,1);
        else  tft.print(Vmax*1.1/255,1);
    
    //ось напряжения##########################################    
   for(byte i=107;i>11; i=i-16) {tft.drawLine( 0, i, 4, i, BLUE); } // черточки слева 
   tft.drawFastVLine(5,12,102,BLUE);tft.drawFastVLine(6,12,102,BLUE);
   //ось времени##########################################
   for(byte i=160;i>7; i=i-16) {tft.drawLine( i, 113, i, 117, RED); } // черточки слева 
   tft.drawFastHLine(7,112,160,RED);tft.drawFastHLine(7,113,160,RED);
 
  // === Отрисовка графика ===    
  for (int y=8; y<160; y++) tft.drawLine(y, 105, y, 105-adcBuf[(y + grOffset)%701]/3.5, GREEN);
  if (pause) { // если пауза - рисуем шкалу прокрутки
    tft.drawLine((grOffset%701)/9,118,(grOffset%701)/9+6,118, BLUE); // шкала прокрутки
    tft.drawLine((grOffset%701)/9,119,(grOffset%701)/9+6,119, BLUE); // шкала прокрутки                
  } else { // если не пауза, то снимаем показания
     while ((ADCSRA & 0x10)==0); // ждем, пока АЦП считает    
     adcBuf[count%701]=ADCH; // сохраняем число из АЦП в массив
     if (count>159) grOffset = count - 160;
     count++;
     if (count>1401) count=701; // зацикливаем счетчик
     //45мс - программа выполняется
     switch (razv) {
       case 0 : delay(55*(overclock/16.0)); break; // секунда на клетку
       case 1 : delay(05*(overclock/16.0)); break; // пол секунды на клетку
       case 2 : break; // без задержки.......
     }
  } 
  if (digitalRead(KEY_L) == HIGH && digitalRead(KEY_R) == HIGH) { delay(1000);
  wdt_enable(WDTO_30MS); while(1) {} ;
  Reset_AVR(); } // soft reset  
  }
   }  
   // === UART приемник === 
  if(mainMenu==3) {  tft.fillScreen(BLACK);   
   while(1){   
   const long speedUart[] = { 1200,2400,4800,9600,19200,38400,57600,115200 };  
  tft.setTextSize(2);
  tft.setTextColor(WHITE, BLUE); 
  tft.setCursor(135, 40); tft.println("+");
  tft.setCursor(25, 40); tft.print("-");
  tft.setTextColor(RED);
  tft.println(" ");      
  tft.print(speedUart[menu]);
  tft.println(" ");
  tft.setCursor(36,15); tft.println("Скорость:");
  tft.setTextColor( GREEN);
  tft.setCursor(18,60); tft.println("ОК - запуск");
  if(digitalRead(KEY_L))  { tft.fillRect( 0, 38, 150, 58, BLACK);
  menu--; if(menu==255) menu=7;   delay(200);  }
  if(digitalRead(KEY_R))  { tft.fillRect( 0, 38, 150, 58, BLACK); 
  menu++; if(menu==8)   menu=0;   delay(200);  }
  if(digitalRead(KEY_OK)) {
    Serial.begin(speedUart[menu]*(16.0/overclock));
    tft.setCursor(25,85);    
    tft.print(">"); 
    delay(200);     
    int x=83;
    while (1) {         
      if (Serial.available()) { // Если в буфере есть данные
        if(++x==84) { // проверяем, не пора ли экран очистить
          x=0;
          tft.fillScreen(BLACK);
        }
        tft.print((char)(Serial.read())); // печать байта в дисплей        
      } 
    }         
  }  
  if (digitalRead(KEY_L) == HIGH && digitalRead(KEY_R) == HIGH) { delay(1000);
  wdt_enable(WDTO_30MS); while(1) {} ;
  Reset_AVR(); } // soft reset   
   }
//############ Частотомер ################
   if(mainMenu==4) {  tft.fillScreen(BLACK);   
   while(1){    
  tft.setTextSize(2); 
  tft.setTextColor(GREEN);
  tft.setCursor(33, 30); tft.println("Частота:"); 
  if(FreqMeasure.available()) {        
  sum = sum + FreqMeasure.read();
  count = count + 1;    if (count > 30) {
  float frequency = FreqMeasure.countToFrequency(sum / count);    
  tft.fillRect( 0, 64, 160, 84, BLACK);     
  tft.setTextColor(RED);  tft.setCursor(24, 65);
  //--------Блок вычисления частоты в ГЦ---------------------
  if (frequency <= 1000){   tft.print(frequency);  tft.println(" Hz");       }
  //--------Блок вычисления частоты в КГЦ---------------------      
  else { float freq = frequency / 1000;  tft.print(freq);  tft.println(" KHz");  }        
  sum = 0;  count = 0;   
    }
  }  
  if (digitalRead(KEY_L) == HIGH && digitalRead(KEY_R) == HIGH) { delay(1000);
  wdt_enable(WDTO_30MS); while(1) {} ;
  Reset_AVR(); } // soft reset     
   }   
   }    
// === Вольтметр === 
  if(mainMenu==5) {  tft.fillScreen(BLACK);   
   while(1){
    tft.setTextSize(2);
tft.setTextColor(GREEN); 
tft.setCursor(10, 25);
tft.print("Вольтметр DC");    
 MsTimer2::set(1, timerInterupt); // прерывания по таймеру, период 1 мс 
  MsTimer2::start();              // разрешение прерывания
 if ( flagReady == true ) {
    flagReady= false;
    // пересчет в напряжение и передача на компьютер
    tft.setTextColor(BLUE);
tft.setCursor(32, 50);
tft.fillRect( 59, 50, 160, 70, BLACK );
tft.print("V= ");
tft.setTextColor(RED);    
    tft.print( (float)avarageU1 * ADC_U_COEFF, 2); 
   }
  if (digitalRead(KEY_L) == HIGH && digitalRead(KEY_R) == HIGH) { delay(1000);
  wdt_enable(WDTO_30MS); while(1) {} ;
  Reset_AVR(); } // soft reset  
   }
   } 
   } 
 
 
      
  
Novice User
Offline
Зарегистрирован: 25.09.2017

Спасибо!

Electronik83
Offline
Зарегистрирован: 06.12.2015

Много знакомых строчек))) Рекомендую спрятать в спойлер.

В транзистор тестере не такой ли экран стоит? 

И вообще, хорошим тоном считается указывать под какой экран заточен скейтч. 

Хоть пару строк описания....

Electronik83
Offline
Зарегистрирован: 06.12.2015

Достал после переезда коробку с ардуинами. Буду заниматься этим проектом дальше. В планах:

1. Создать мини faq (раньше давно был);

2. Перенос версии 18 на omaled ssd (забыл как называется);

3. Исправление ошибки с отображением частоты (спектрум тыкал - там как то с частотами не то);

4. Перезагрузка с кнопок.

5. Очень хочу добавить сохранение настроек всех значений пользователя в еепром! Но вышел затык с контрастом....

6. Непонятка с питанием от лития и измерения напряжений- надо разобраться.

7. Просмотрел много скейтчев - в одном из них увидел вольтметр - на кой черт он нужен?!?!

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Electronik83 пишет:

И вообще, хорошим тоном считается указывать под какой экран заточен скейтч. 

Skaytch ?   Слово Sketch  по-русски и по-английски произносится как скетч.

Electronik83
Offline
Зарегистрирован: 06.12.2015

Мне это слово сразу не понравилось. Приму к сведенью))))

MIK22
Offline
Зарегистрирован: 09.02.2017

Дисплей ST7735S.

Входные пины А3 Д8. Д8 определен библиотекой FreqMeasure. Она занимает меньше места.

Функция ZAMER для massduino и wemos NANO у меня заработала только в таков виде, хотя это одно и тоже

      //while ((ADCSRA & 0x10)==0);   // ждем готовность АЦП
      //ADCSRA|=0x10;                 // запускаем следующее преобразование
      while(ADCSRA & (1<<ADSC)); 
      ADCSRA |= 1<<ADSC;
 Для wemos NANO не нашел аппаратный SPI поэтому дисплей подключен по програмному. Для massduino все нормально работает.
Вольтметр до 30 вольт. коэффициунт расчитан для аходного делителя.
Была еще прозвонка но сделать ее на тех же входных пинах не получилось, а делать дополнительный вход не хотелось.
alex_c
Offline
Зарегистрирован: 22.06.2018

парни добрый день кто подскажет как можно сделать может кто делал развертку (сек/дел) больше чем у оригинала?

мне просто надо что бы было 1-2 сек на деление

Electronik83
Offline
Зарегистрирован: 06.12.2015

Дак в моей версии там есть.....

alex_c
Offline
Зарегистрирован: 22.06.2018

а где ознакомится можно?

Electronik83
Offline
Зарегистрирован: 06.12.2015

https://yadi.sk/d/OWt4M28A3ULLcf

Последняя нормальная версия... для 5110

alex_c
Offline
Зарегистрирован: 22.06.2018

спасибо я посматрел но на 0 тоже самое ( а это много

Electronik83
Offline
Зарегистрирован: 06.12.2015

alex_c пишет:

спасибо я посматрел но на 0 тоже самое ( а это много

Там отдельный режим сделан - снятие АЧХ. Он медленный.

alex_c
Offline
Зарегистрирован: 22.06.2018

да спасибо нашел)

Electronik83
Offline
Зарегистрирован: 06.12.2015

Чет у меня походу SSD1306 накрылся..... блин я в печали... хотел переписать под него и не работатет экранчик....

Andry Smart
Offline
Зарегистрирован: 06.09.2016

вот блин а я так ждал.... и что теперь делать? как по мне этот экран рожден для пультоскопа.

weisswp
Offline
Зарегистрирован: 26.05.2018

эх.. и я ждал (

slider
Offline
Зарегистрирован: 17.06.2014

Electronik83 пишет:

Чет у меня походу SSD1306 накрылся..... блин я в печали... хотел переписать под него и не работатет экранчик....

подикась напрямую к ардуине зацепляли , без делителей ?

MIK22, вроде massduino может работать на 32МГц ? по идее , после заливки скетча с настройками надо перепаять кварц, должно заработать.

Electronik83
Offline
Зарегистрирован: 06.12.2015

Дак дисплей этот очень долго так работал. Тем более на плате у самого дисплея распаяны делители. Я переписал прогу под него, запустил и все. Кирдык ему. Могу поделиться скетчем убицом таких дисплеев)))) Или может он мехаеически пострадал. В общем не до конца понятно что случилось)

alexey561
Offline
Зарегистрирован: 23.06.2018

Здравствуйте, сделал осциллограф с усилителем и смещением нуля, возникла проблема как измерить напряжение входного сигнала? Может у кого нибудь есть идеи? https://youtu.be/si_QmqxYATE

alexey561
Offline
Зарегистрирован: 23.06.2018

Буду благодарен за любую информацию

weisswp
Offline
Зарегистрирован: 26.05.2018

сомневаюсь, что можно программно убить дисплей, поэтому готов рискнуть одним из своих)

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Дисплеи умирают от того, что не рассчитаны на работу с 5-вольтовыми МК. Недавно писал как узнать совместимый с 5в дисплей.

VicSan
Offline
Зарегистрирован: 27.04.2017

я сразу себе делители поставил.