// //Страница проэкта http://srukami.inf.ua/pultoscop_v25110.html //Переделка под дисплей от Nokia 3410 и оптимизация кода http://best-chart.ru #include #include #include #include #define led 10 //пин для генератора сигналов (Только 9й или 10й пин) //#################№№№№№№####пользовательские настройки #define levo 11 //кнопка ЛЕВО(можно любой пин) #define ok 8 //кнопка ОК(можно любой пин) #define pravo 12 //кнопка ПРАВО(можно любой пин) #define akb A6 //любой свободный аналоговый пин для измерения напряжения АКБ #define overclock 16 //Частота на которой работает Ардуино Adafruit_PCD8544 display = Adafruit_PCD8544(2, 3, 4, 6, 7);//пины к которым у вас подключен дисплей byte cont=75;//контрастность дисплея byte SinU=5; //уровень синхронизации 0 до 255 int PWM = 100;//стартовое значение ШИМ от 0 до 255 float fiveV = 5.13; //наши 5v, меряем мультиметром int32_t frequency = 5000; //стартовое значение частоты в Гц //########################################################### float maxV = 0.0; // вычисление вольтажа float printV = 0.0; // вывод вольтажа float batt =0.00; // для вывода вольтажа батареи byte hag=0; int mnog=0; boolean flag=0; byte mass[256]; byte x=0; byte menu=0;//переменная выбора меню bool opornoe=1; //флаг опорного напряжения bool paus=0; //флаг режима паузы bool pultoskop=1; //флаг выбора генератора или осциллографа byte razv=6; byte sinhMASS=0; long countX=0; byte zoom=1; //Приближение по умолчанию 1:1 byte poz=8; //Позиционирование int koef=1; //коэффициент для синхронизации int newpoz=0; unsigned long count =0; void setup(){ display.begin(); display.setContrast(cont); display.clearDisplay(); display.setCursor(5,20); display.setTextColor(BLACK); display.print("Pultoscope v."); display.setCursor(82,13); display.setTextSize(2); display.print("2"); display.setTextSize(1); display.setCursor(3,45); display.println(utf8rus("Версия для 3410")); display.setCursor(10,55); display.print("best-chart.ru"); batt=analogRead(akb)*fiveV/1024; display.display(); delay(2000); while(digitalRead(ok)==LOW){ display.clearDisplay(); display.setCursor(15,10); display.println(utf8rus("Осциллограф")); display.setCursor(15,20); display.println(utf8rus("Генератор")); display.setCursor(15,30); display.println(utf8rus("Новая Функция")); display.setCursor(5,55); display.print(utf8rus("Батарея ")); display.print(batt); display.println(utf8rus(" в")); if(pultoskop==1) display.setCursor(5,10); if(pultoskop==0) display.setCursor(5,20); if(pultoskop==2) display.setCursor(5,30); display.print(">"); display.display(); if(digitalRead(levo)==HIGH){ if(pultoskop>1) pultoskop--; } if(digitalRead(pravo)==HIGH){ if(pultoskop<2) pultoskop++; } } if(pultoskop==1){ FreqCount.begin(1000); } if(pultoskop==0){ InitTimersSafe(); bool success = SetPinFrequencySafe(led, frequency); } display.setTextColor(BLACK); delay(500); } void Zamer(){ if (razv>=6){ADCSRA = 0b11100010;}//delitel 4 if (razv==5){ADCSRA = 0b11100011;}//delitel 8 if (razv==4){ADCSRA = 0b11100100;}//delitel 16 if (razv==3){ADCSRA = 0b11100101;}//delitel 32 if (razv==2){ADCSRA = 0b11100110;}//delitel 64 if (razv<2){ADCSRA = 0b11100111;}//delitel 128 if (razv==0){ for(byte i=0;i<255;i++){ while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; delayMicroseconds(500); mass[i]=ADCH; } } if (razv>0){ for(byte i=0;i<255;i++){ while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; mass[i]=ADCH; } } } void loop() { if(pultoskop==1){ String text=""; byte test; if(opornoe==0){ADMUX = 0b11100100;}//выбор внутреннего опорного 1,1В if(opornoe==1){ADMUX = 0b01100100;}//Выбор внешнего опорного delay(5); if(paus==0){Zamer();} //#######################################определение точки синхронизации maxV = 0; for(int y=1;y<85;y++){ if(maxV=85) koef=1; else { if(maxV>=17) koef=3; else koef=15; } } bool flagSINHRO=0; bool flagSINHRnull=0; for(int y=1;y<255;y++){ if(flagSINHRO==0){if(mass[y]*koefSinU){flagSINHRO=1;sinhMASS=y;}} } } //if(flagSINHRO==0){if(mass[y]SinU){flagSINHRO=1;sinhMASS=y;}} //#######################################отрисовка графика x=10; if (zoom==2) x=5; if (zoom==3) x=3; if(poz==9) newpoz=-14; if(poz==8) newpoz=0; if(poz==7) newpoz=7; if(poz==6) newpoz=14; if(poz==5) newpoz=21; if(poz==4) newpoz=28; if(poz==3) newpoz=35; if(poz==2) newpoz=42; if(poz==1) newpoz=49; display.clearDisplay(); display.fillCircle(91,45-SinU/5.8, 2, BLACK);//рисуем уровень синхронизации //for(int y=1;y<85;y++){ for(int y=sinhMASS;y=0;i=i-9){display.drawFastHLine(0,i,9, BLACK);} for(int i=9; i<95; i+=5) { display.drawPixel(i,18, BLACK); display.drawPixel(i,36, BLACK); } display.drawChar (0, 14, '9', 1, 0, 1); display.drawChar (0, 33, '3', 1, 0, 1); if(maxV<85) { display.drawChar (0, 14, '3', 1, 0, 1); display.drawChar (0, 33, '1', 1, 0, 1); } if(maxV<17) { display.drawChar (-1, 14, '.', 1, 0, 1); display.drawChar (-1, 33, '.', 1, 0, 1); display.drawChar (3, 14, '6', 1, 0, 1); display.drawChar (3, 33, '2', 1, 0, 1); } } //#######################################отрисовка menu display.fillRect(0, 47, 95, 18, 0); if(menu==0){ if(digitalRead(levo)==HIGH){opornoe=!opornoe;} if(digitalRead(pravo)==HIGH){opornoe=!opornoe;} display.drawRect(0, 46, 9, 11, BLACK); } if(menu==1){ if(digitalRead(levo)==HIGH){razv=razv-1;if(razv==255){razv=0;}} if(digitalRead(pravo)==HIGH){razv=razv+1;if(razv==9){razv=8;}} display.drawRect(12, 46, 21, 11, BLACK); } if(menu==2){ if(digitalRead(levo)==HIGH){zoom=zoom-1;if(zoom==0){zoom=1;}} if(digitalRead(pravo)==HIGH){zoom=zoom+1;if(zoom==4){zoom=3;}} display.drawRect(36, 46, 21, 11, BLACK); } if(menu==3){ if(digitalRead(levo)==HIGH) {poz=poz-1;if(poz==0){poz=1;}} if(digitalRead(pravo)==HIGH){poz=poz+1;if(poz==10){poz=9;}} display.drawRect(60, 46, 21, 11, BLACK); } if(menu==4){ paus=1; if(digitalRead(levo)==HIGH){Zamer();} if(digitalRead(pravo)==HIGH){Zamer();} display.drawRect(82, 46, 11, 11, BLACK); } if(menu==5){ paus=0; if(digitalRead(levo)==HIGH){if(SinU>=25){SinU=SinU-20;}} if(digitalRead(pravo)==HIGH){if(SinU<=225){SinU=SinU+20;}} display.fillCircle(91,45-SinU/5.8, 3, BLACK); display.fillCircle(91,45-SinU/5.8, 2, WHITE); } if(digitalRead(ok)==HIGH){menu++;if(menu==6){menu=0;paus=0;}}//перебор меню if (FreqCount.available()) {count = FreqCount.read();}//вывод частоты по готовности счетчика countX=count*(overclock/16.0); if(countX==0) { //#######################################частоты сигнала byte Frec1=0; int Frec=0; bool flagFrec1=0; bool flagFrec2=0; bool flagFrec3=0; for(int y=1;y<255;y++){ if(flagFrec1==0){if(mass[y]*koefSinU){flagFrec1=1;Frec1=y;}}} if(flagFrec1==1){if(mass[y]*koefSinU){ if (razv>=6){Frec=1000000/((y-Frec1-1)*3.27);}//delitel 4 if (razv==5){Frec=1000000/((y-Frec1)*3.27)/2;}//delitel 8 if (razv==4){Frec=1000000/((y-Frec1)*3.27)/4;}//delitel 16 if (razv==3){Frec=1000000/((y-Frec1)*3.27)/8;}//delitel 32 if (razv==2){Frec=1000000/((y-Frec1)*3.27)/16;}//delitel 64 if (razv==2){Frec=1000000/((y-Frec1)*3.27)/32;}//delitel 128 if (razv==1){Frec=1000000/((y-Frec1)*3.27)/32;}//delitel 128 if (razv==0){Frec=1000000/((y-Frec1)*500);}//delitel 128 flagFrec1=0;flagFrec3=0;}}} //#######################################частоты сигнала countX=Frec*(overclock/16.0); } if(opornoe==0) text="1"; if(opornoe==1) text="5"; text=text+utf8rus(" Р:")+razv+utf8rus(" ")+zoom+utf8rus(":1")+utf8rus(" П:")+poz; display.setCursor(2, 48); display.print(text); if(opornoe==1) printV=maxV*fiveV/255*3,2; //if(opornoe==1) printV=maxV*fiveV/255*3,2; if(opornoe==0) printV=maxV*1.10/255*3,2; // напряжение на делителе 1.1в display.setCursor(1, 58); display.print(printV);display.print("v "); display.print(countX);display.print("Hz"); display.fillRect(85, 48, 2, 7, 1); display.fillRect(88, 48, 2, 7, 1); //display.setCursor(55, 0); display.print(maxV); //градации напряжения //#######################################отрисовка menu display.display(); delay(300); } if(pultoskop==0){Generator();} if(pultoskop==2){New_function();} } //#######################################режим ренератора void Generator(){ display.clearDisplay(); if (flag==0){//флаг выборов режима настройки ШИМ или Частоты if(digitalRead(levo)==HIGH){ frequency=frequency-mnog; if(frequency<0){frequency=0;} bool success = SetPinFrequencySafe(led, frequency); delay(3);//защита от дребезга } if(digitalRead(pravo)==HIGH){ frequency=frequency+mnog; bool success = SetPinFrequencySafe(led, frequency); delay(3);//защита от дребезга } } if (flag==1){//флаг выборов режима настройки ШИМ или Частоты if(digitalRead(levo)==HIGH){ PWM=PWM-3; if(PWM<0){PWM=255;} delay(3);//защита от дребезга } if(digitalRead(pravo)==HIGH){ PWM=PWM+3; if(PWM>255){PWM=0;} delay(3);//защита от дребезга } } if(digitalRead(ok)==HIGH){//переключение разряда выбора частоты delay(3);//защита от дребезга hag++; if(hag>=5){hag=0;} } //////////// display.setTextSize(1); display.setCursor(20,15); display.print("PWM = "); display.print(PWM*100/255); display.print("%"); display.drawRect(2,2,92,10, BLACK); display.fillRect(2,2,92*PWM/255.0,10, BLACK); /////////// display.setCursor(5,30); display.setTextSize(2); long frequencyX=frequency*(overclock/16.0); if(frequencyX<1000){display.print(frequencyX);display.setTextSize(1);display.println("Hz");} if(frequencyX>=1000){if(frequencyX<10000){display.print((frequencyX/1000.0),3);display.setTextSize(1);display.println("KHz");}} if(frequencyX>=10000){if(frequencyX<100000){display.print((frequencyX/1000.0),3);display.setTextSize(1);display.println("KHz");}} if(frequencyX>=100000){display.print((frequencyX/1000.0),2);display.setTextSize(1);display.println("KHz");} display.setCursor(15,55); display.setTextSize(1); display.print(">> X "); if(hag==0){//выбор множителя частоты display.print(1*(overclock/16.0),1); mnog=1; flag=0; } if(hag==1){//выбор множителя частоты display.print(10*(overclock/16.0),0); mnog=10; } if(hag==2){//выбор множителя частоты display.print(100*(overclock/16.0),0); mnog=100; } if(hag==3){//выбор множителя частоты display.print(1000*(overclock/16.0),0); mnog=1000; } if(hag==4){//выбор PWM display.print(utf8rus("ШИМ")); flag=1; } display.print(" <<"); pwmWrite(led, PWM); display.display(); delay(300); } //#######################################режим новой функции void New_function(){ display.clearDisplay(); display.setTextSize(1); display.setCursor(5,5); display.print("Место новой функции "); display.display(); delay(500); }