Дисплей ILI9163C смотрится симпатичнее чем дисплей от Nokia. И разрешение побольше, да и цвет присутствует. Поэтому автору бодрому2014 рекомендовал (скорее просил) сделать осцилоскоп с таким дисплеем.
Нет такого дисплея под рукой. Но назрела потребность переделать пультоскоп или сделать новый.
Доброго времени ! Подключил ваш PULTOSCOP к дисплею ILI9163C очень красиво смотрится! конечно сделал пока без обвязки входов,это поэтому дисплей и показания моргают?
У меня почему то когда соединяю А5 с D5 для измерения частоты,то сразу показывает 50гц,причем провод рукой не трогаю. В чем может быть дело,кто то сталкивался с таким?
У меня почему то когда соединяю А5 с D5 для измерения частоты,то сразу показывает 50гц,причем провод рукой не трогаю. В чем может быть дело,кто то сталкивался с таким?
В скетче на А5 потенциометр.
D5 с А4 соединять нужно.
Для проверки подайте на D5 землю если пропадет значит просто ловит наводку.
В скетче от автора есть функция дисплея display.display(); что она значит,подскажите? В моем дисплее ILI9163такая функция не компилируется! Поэтому я ее убрал,вопрос-может ли она сказатся на работе дисплея?
Понял,спасибо за консультации! Еще вопрос,моргание дисплея как можно убрать? Ведь используется функция очистки дисплея
//display.clearDisplay();
tft.clearScreen(); А у вас на видео этого моргания не видно ! регулируя потенциомметр,частота моргания меняется конечно,но нет как у вас.Чем можно убрать это мигание к минимуму?
А скетч с доработанными кнопками где? Я заливал себе скетч от Noriaki Mitsunaga" (как в 203 посте), но только практчески все аналоговые входы UNO заняты экраном, кроме "А5" а в скетче вовсе указаны входы "А6" и "А7", которых в Arduino UNO совсем нет. Я только один канал на А5 задействовал а второй 5вольт показывал постоянно.
Сырой пока чтобы выкладывать. Нужно настроить на работу сначала.... сейчас думаю как щуп сделать
Если скорость развертки меняет-сгодится и сырой. Скиньте код, пожалуйста.
Нашел решение проблеммы на своем примере пультоскопа от bodriy2014 от произвольного изменения контраста дисплея от нокии 5110 (был у меня такой вопросик) На плате с которой постовляется дисплей, присутствует керамический чип кондедсатор на 0,1мкф, который походу перенасыщяется из-за не установленых на spi входах огранечительных резисторов, решил пойти подругому, припаял паролельно ему резистор на 1мом, и контраст остается пока на своем установленом в скетче параметре
Нашел решение проблеммы на своем примере пультоскопа от bodriy2014 от произвольного изменения контраста дисплея от нокии 5110 (был у меня такой вопросик) На плате с которой постовляется дисплей, присутствует керамический чип кондедсатор на 0,1мкф, который походу перенасыщяется из-за не установленых на spi входах огранечительных резисторов, решил пойти подругому, припаял паролельно ему резистор на 1мом, и контраст остается пока на своем установленом в скетче параметре
Здравствуйте,мне понравился ваш проэкт,хочу повторить,дисплей у меня есть,а вот ардуино нету,но есть мега 328 в TQFP корпусе,возможно ли собрать ваш осциллограф без ардуино?
Здравствуйте,мне понравился ваш проэкт,хочу повторить,дисплей у меня есть,а вот ардуино нету,но есть мега 328 в TQFP корпусе,возможно ли собрать ваш осциллограф без ардуино?
Возможно собрать на любой Atmega328.
TQFP корпус требует только более мелкие дорожки.
Нужен еще будет кварц на 16МГц, несколько резисторов и конденсаторов, кнопок.
bodriy2014! Здравстауйте! Подскажите пожалуйста, как будет выглядеть схема делителя 1|10? Подтягивал к минусу резистор 100ком. Никакие сигналы не проходят! Может конденсатор в этом случае нужно убрать? За ранее спасибо!
bodriy2014! Здравстауйте! Подскажите пожалуйста, как будет выглядеть схема делителя 1|10? Подтягивал к минусу резистор 100ком. Никакие сигналы не проходят! Может конденсатор в этом случае нужно убрать? За ранее спасибо!
конденсатор не остановит переменный ток, можете убрать можете оставть.
Спасибо большое !Буду подключать и пробовать. Еще вопрос-Если берусь за минусовой провод рукой,то тоже показывает порядка 50гц! Это нормально или наводки?
bodriy2014,здравствуйте! Вопрос, обратил внимание,что при тестировании с генератора сигналов,если сигнал меньше 2 вольт,то частоту не считывает,то есть показывает ноль,хотя форма сигнала правильная! Можете как то пояснить с чем это связано?
bodriy2014,здравствуйте! Вопрос, обратил внимание,что при тестировании с генератора сигналов,если сигнал меньше 2 вольт,то частоту не считывает,то есть показывает ноль,хотя форма сигнала правильная! Можете как то пояснить с чем это связано?
Легко.
Частоту меряет апаратно с порта D5, и на цифровых портах все что ниже 1,8В считается нулем что выше еденица.(могу незначительно ошибиться смотрите даташит)
bodriy2014 добрый вечер! Сигнал до 2 вольт он не так и важен! Но как сделать с делителем ,чтобы онс 2в.- до 50 вольт воспринимал сигнал? Или так не получится?За ранее спасибо!
bodriy2014 добрый вечер! Сигнал до 2 вольт он не так и важен! Но как сделать с делителем ,чтобы онс 2в.- до 50 вольт воспринимал сигнал? Или так не получится?За ранее спасибо!
Да как сделать, руками я думаю)))
Без делителя он берет сигнал до 5В.
Если хотите до 50В собирайте щуп с делителем 1 к 10 и подключайте, можно продумать переключатель чтоб делитель переключать.
Но если делитель 1\10 то при 20 в и меньше на входе мк будет кокрас 2в. и меньше,то есть от 20 в и меньше снова будет мертвая зона! Единственное пока что я вижу это делать делители 1\2 , 1\5, 1\10 и т.д тогда будет перекрыватся мертвая зона на верхних пределах меньших делителей? Как вы считаете?
Здорово получается. А как он справляется с изменяющимся сигналом имеющим несколько гармоник? В нём нет синхронизации, она будет реализована паузой, записью определённого количества выборок и её отображением на дисплей с возможностью сдвига в обе стороны для просмотра? Хотелось бы увидеть на видео изменяющийся сигнал с гармониками и на верхнем пределе возможности, тоесть увеличивать частоту отображаемого сигнала, растяжку его по времени. Вещь замечательная, для тех кто занимается чисто Ардуино или вообще низкочастотными цифровыми сигналами, как переносной логический проник.
Перед тем как отвечать скажу сразу, хорошие вопросы мне обычно подсказывают как и что улучшить!)
Теперь по рядку
--Для него самой тяжело отображаемый сигнал это меандр, все что имеет скругленные форму может отображаться на более высоких частотах.Гармоники покажу на следующем видео.
--Синхронизацию могу реализовать пока только програмно, запись данных в буфер и отображение буфера с учетом оной. Пауза будет только замораживать отображение без прокрутки, кнопками будем листать не буфер в зад и вперед, а заново его наполнять. Если будет работать неудобно изменю.
--Тест верхних пределов будет в следующем видео в разогнанном состоянии и в стоковом.
Пока доступна полоса пропускания в стоке 300К и в разгоне 600К. Очень хочется реализовать эфект стробоскопа чтоб увеличить полосу пропускания до 8МГц, пробовал по быстрому написать не получилось((
Отличный прибор получается!Буду следить,обязательно за ходом разработки.Такой прибор очень нужен.Пока буду использовать на экране 5110.Автор-спасибо огромное за труды!!!!
bodriy2014, привет! Отличный прибор получается. Четкие задачи, выполнение на высоком уровне! Скажи какие компоненты сейчас ипользуются, чтоб можно было потихоньку прикупать. То идти они могут очень долго. Arduino 5ти вольтовая? Питание сам делал или модуль? Экран любой определенного разрешения или конкретная модель? Какая? О чем еще нужно заранее позаботиться?
bodriy2014, Да... планов настроенно!)) Удачи в их реализации! Я пока прикуплю ардуинку, может чего с дисплеем решу (есть в наличии китайские телефоны с дисплеями такого разрешения, нужно выяснить на каких контроллерах они работают).
bodriy2014, приветствую Вас. Респект Вам за проделанную работу. А новый экранчик у Вас вроде бы сенсорный, отчего же решили управление кнопочками делать?
Дисплей ILI9163C смотрится симпатичнее чем дисплей от Nokia. И разрешение побольше, да и цвет присутствует. Поэтому автору бодрому2014 рекомендовал (скорее просил) сделать осцилоскоп с таким дисплеем.
Нет такого дисплея под рукой. Но назрела потребность переделать пультоскоп или сделать новый.
Доброго времени ! Подключил ваш PULTOSCOP к дисплею ILI9163C очень красиво смотрится! конечно сделал пока без обвязки входов,это поэтому дисплей и показания моргают?
https://yadi.sk/d/cI4Dp4dHm2mSt
вот ссылка на фото с дисплеем. Подскажите пожалуйста переменный резистор ,для чего он нужен? За ранее спасибо!
Переменник регулирует развертку. Без него не рассмотрите ничего в мельтешении на экране.
У меня почему то когда соединяю А5 с D5 для измерения частоты,то сразу показывает 50гц,причем провод рукой не трогаю. В чем может быть дело,кто то сталкивался с таким?
У меня почему то когда соединяю А5 с D5 для измерения частоты,то сразу показывает 50гц,причем провод рукой не трогаю. В чем может быть дело,кто то сталкивался с таким?
В скетче на А5 потенциометр.
D5 с А4 соединять нужно.
Для проверки подайте на D5 землю если пропадет значит просто ловит наводку.
bodriy2014, какие работы планируются? Как скоро выйдет обновленный пультоскоп?
В скетче от автора есть функция дисплея display.display(); что она значит,подскажите? В моем дисплее ILI9163такая функция не компилируется! Поэтому я ее убрал,вопрос-может ли она сказатся на работе дисплея?
.....! Поэтому я ее убрал,вопрос-может ли она сказатся на работе дисплея?
она нужна только для той библиотеки что у меня.
У вас другой дисплей и своя библиотека вам она не нужна.
Понял,спасибо за консультации! Еще вопрос,моргание дисплея как можно убрать? Ведь используется функция очистки дисплея
Нет такого дисплея под рукой. Но назрела потребность переделать пультоскоп или сделать новый.
Спасибо. Будем ждать.
А скетч с доработанными кнопками где? Я заливал себе скетч от Noriaki Mitsunaga" (как в 203 посте), но только практчески все аналоговые входы UNO заняты экраном, кроме "А5" а в скетче вовсе указаны входы "А6" и "А7", которых в Arduino UNO совсем нет. Я только один канал на А5 задействовал а второй 5вольт показывал постоянно.
Сырой пока чтобы выкладывать. Нужно настроить на работу сначала.... сейчас думаю как щуп сделать
Если скорость развертки меняет-сгодится и сырой. Скиньте код, пожалуйста.
Нашел решение проблеммы на своем примере пультоскопа от bodriy2014 от произвольного изменения контраста дисплея от нокии 5110 (был у меня такой вопросик) На плате с которой постовляется дисплей, присутствует керамический чип кондедсатор на 0,1мкф, который походу перенасыщяется из-за не установленых на spi входах огранечительных резисторов, решил пойти подругому, припаял паролельно ему резистор на 1мом, и контраст остается пока на своем установленом в скетче параметре
Нашел решение проблеммы на своем примере пультоскопа от bodriy2014 от произвольного изменения контраста дисплея от нокии 5110 (был у меня такой вопросик) На плате с которой постовляется дисплей, присутствует керамический чип кондедсатор на 0,1мкф, который походу перенасыщяется из-за не установленых на spi входах огранечительных резисторов, решил пойти подругому, припаял паролельно ему резистор на 1мом, и контраст остается пока на своем установленом в скетче параметре
Гг, чтото новенькое, "насыщение конденсатора".
ну у меня только такое определение возникает
Доброго времени всем! Доработа скетч с работой на дисплее ILI9163C,все работает прекрасно! Убрал моргание экрана,добавил раскраски.
Этот проект по функционалу мне кажется даже лучше,чем предыдущий.Ничего лишнего,только необходимые параметры и форма сигнала.Рекомендую всем. Скетч
#include <Adafruit_GFX.h> // #include <Adafruit_PCD8544.h> #include <SPI.h> #include <FreqCount.h> #include <TFT_ILI9163C.h> // Color definitions #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define __CS 10 #define __DC 9 TFT_ILI9163C tft = TFT_ILI9163C(__CS, 8, __DC); #define DISPLAY_WIDTH 128 #define DISPLAY_HEIGHT 128 #define ARDUINO_PRECISION 1023.0 // Adafruit_PCD8544 display = Adafruit_PCD8544(14, 13, 12, 11, 10); int channelAI = A4; //вход сигнала А5, частоту меряем на 5!!! int PINakum = A6; //вход замера аккумулдятора int delayAI = A5; //делитель нп потенциометре int razv = 0;// константы и пины добавления развертки int oldRazv=0; #define DELAY_POTENTIMETER #ifdef DELAY_POTENTIMETER #endif float delayVariable = 0; float scale = 0; int xCounter = 0; int yPosition = 0; int readings[DISPLAY_WIDTH + 1]; int oldReadings[DISPLAY_WIDTH + 1]; int counter = 0; unsigned long drawtime = 0; unsigned long lastdraw = 0; unsigned long count = 0; int frames = 0; float analog=0; unsigned long oldCount=0; void setup() { FreqCount.begin(1000); tft.begin(); tft.setRotation(3); tft.fillScreen(BLACK); tft.setCursor(25, 5); tft.print("PULTOSCOPE"); tft.setCursor(15, 15); tft.print("Mobile v1.1"); //#################тест аккумулятора if ((analogRead(PINakum) / ARDUINO_PRECISION * 5.0) > 3.3) { tft.setCursor(10, 30); tft.print("Test Batt OK!"); } if ((analogRead(PINakum) / ARDUINO_PRECISION * 5.0) < 3.3) { tft.setCursor(10, 30); tft.print("Test Batt NO!"); } tft.setCursor(40, 45); tft.print(analogRead(PINakum) / ARDUINO_PRECISION * 5.0); tft.print("V"); //tft.display(0); delay(3000); tft.clearScreen(); //####################### } void loop() { #ifdef DELAY_POTENTIMETER delayVariable = analogRead(delayAI); delayVariable = (delayVariable / 100); //делитель регулирует выборку #endif //scale = (float)(DISPLAY_HEIGHT-1)/ARDUINO_PRECISION; scale = 127 / 1210.0; //ограничиваем диаграмму на один символ сверху //##############################################разделение шкалы по сигналу for (xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++) { oldReadings[xCounter] = readings[xCounter]; } for (xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++) { yPosition = analogRead(channelAI); readings[xCounter] = (yPosition * scale); #ifdef DELAY_POTENTIMETER delay (delayVariable ); #endif } //##############################################шкала напряжений tft.drawLine( 10, 20, 10, DISPLAY_HEIGHT - 1, RED); tft.drawLine( 5, (DISPLAY_HEIGHT - 1) - (.2 * ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT - 1) - (.2 * ARDUINO_PRECISION * scale), RED); tft.drawLine( 5, (DISPLAY_HEIGHT - 1) - (.4 * ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT - 1) - (.4 * ARDUINO_PRECISION * scale), RED); tft.drawLine( 5, (DISPLAY_HEIGHT - 1) - (.6 * ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT - 1) - (.6 * ARDUINO_PRECISION * scale), RED); tft.drawLine( 5, (DISPLAY_HEIGHT - 1) - (.8 * ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT - 1) - (.8 * ARDUINO_PRECISION * scale), RED); tft.setTextColor(MAGENTA); tft.setCursor(0, ((DISPLAY_HEIGHT - 1) - (.2 * ARDUINO_PRECISION * scale)) - 3); tft.print((int)(5.0 * 0.2)); tft.setCursor(0, ((DISPLAY_HEIGHT - 1) - (.4 * ARDUINO_PRECISION * scale)) - 3); tft.print((int)(5.0 * 0.4)); tft.setCursor(0, ((DISPLAY_HEIGHT - 1) - (.6 * ARDUINO_PRECISION * scale)) - 3); tft.print((int)(5.0 * 0.6)); tft.setCursor(0, ((DISPLAY_HEIGHT - 1) - (.8 * ARDUINO_PRECISION * scale)) - 3); tft.print((int)(5.0 * 0.8)); //##############################################отрисовка сигнала for (xCounter = 14; xCounter <= DISPLAY_WIDTH; xCounter++) { tft.drawPixel(xCounter, (DISPLAY_HEIGHT - 1) - readings[xCounter], RED); if (xCounter > 1) { tft.drawLine(xCounter - 1, (DISPLAY_HEIGHT - 1) - oldReadings[xCounter - 1], xCounter, (DISPLAY_HEIGHT - 1) - oldReadings[xCounter], BLACK); tft.drawLine(xCounter - 1, (DISPLAY_HEIGHT - 1) - readings[xCounter - 1], xCounter, (DISPLAY_HEIGHT - 1) - readings[xCounter], RED); } } tft.setTextColor(BLACK); tft.setCursor(90, 5); tft.print(oldRazv); tft.setTextColor(WHITE); tft.setCursor(90, 5); tft.print(razv); oldRazv=razv; //############################################вывод напряжения tft.setTextColor(BLACK); tft.setCursor(5, 5); tft.print(analog); tft.setTextColor(WHITE); tft.setCursor(5, 5); analog= analogRead(channelAI) / ARDUINO_PRECISION * 5.0; tft.print(analog); tft.print("V"); if (count < 1000) { tft.setTextColor(BLACK); tft.setCursor(42, 5); tft.print(count); tft.print("Hz"); } if (count > 1000) { tft.setTextColor(BLACK); tft.setCursor(42, 5); tft.print((count) / 1000); tft.print("KHz"); } if (FreqCount.available()) { count = FreqCount.read(); } if (count < 1000) { tft.setTextColor(MAGENTA); tft.setCursor(42, 5); tft.print(count); tft.print("Hz"); } if (count > 1000) { tft.setTextColor(MAGENTA); tft.setCursor(42, 5); tft.print((count) / 1000); tft.print("KHz"); } if (digitalRead(2) == HIGH) // проверяем состояние кнопки { razv = razv + 5; } if (digitalRead(3) == HIGH) // проверяем состояние кнопки { razv = razv - 5; if (razv < 0) // проверяем состояние кнопки { razv = 0; } } delay(razv);//регулирует частоту выборки }Отлично, фото дисплея в работе не скините?
фото есть выше
но повторю
https://yadi.sk/d/cI4Dp4dHm2mSt
Доработал pultoscop переписал весь код с ноля, прошлый был частично по кускам собран из чужих.
--Теперь частота выборки АЦП будет 300 000 циклов в секунду.
--доработал управление графиком теперь все можно рассмотреть и даже заморозить.
--убрал потенциометр все только кнопками.
--все настройки сохраняются в энергонещависимую память.
--счас занимаюсь печаткой и дорабатываю функцию "АВТО"
--еще пару плюшек есть но это когда выложу весь материал.
....................................
--еще пару плюшек есть но это когда выложу весь материал.
Ждем. Давно хочу повторить конструкцию. Значит не зря ждал :) Буду делать новую версию.
Доработал pultoscop переписал весь код с ноля,
Здорово! Хороший подарок всем на НГ)) Интересно что получилось. Базовые компоненты те же (Pro mini + дисплей 3310)?
Здорово! Хороший подарок всем на НГ)) Интересно что получилось. Базовые компоненты те же (Pro mini + дисплей 3310)?
Привет.
Да подарок из разряда сделай сам))
Компоненты
--любой ардуино где стоит Atmega328/
--Дисплей 5110/3310.
У меня и побольше есть дисплеи от друхих мобилок и даже цветные с неплохим разрешением, но тогда повторяемось упадет, где другие такой брать будут.
Будут предложения по функционалу пишите, ветку читаю смогу-добавлю!
--любой ардуино где стоит Atmega328/
Здравствуйте,мне понравился ваш проэкт,хочу повторить,дисплей у меня есть,а вот ардуино нету,но есть мега 328 в TQFP корпусе,возможно ли собрать ваш осциллограф без ардуино?
--любой ардуино где стоит Atmega328/
Здравствуйте,мне понравился ваш проэкт,хочу повторить,дисплей у меня есть,а вот ардуино нету,но есть мега 328 в TQFP корпусе,возможно ли собрать ваш осциллограф без ардуино?
Возможно собрать на любой Atmega328.
TQFP корпус требует только более мелкие дорожки.
Нужен еще будет кварц на 16МГц, несколько резисторов и конденсаторов, кнопок.
Спасибо!
А где можно схемку глянуть?
Спасибо!
А где можно схемку глянуть?
пост 267
первое предложение содержит ссылку на первую версию.
в последнем предложении ответ на последнюю версию.
bodriy2014! Здравстауйте! Подскажите пожалуйста, как будет выглядеть схема делителя 1|10? Подтягивал к минусу резистор 100ком. Никакие сигналы не проходят! Может конденсатор в этом случае нужно убрать? За ранее спасибо!
bodriy2014! Здравстауйте! Подскажите пожалуйста, как будет выглядеть схема делителя 1|10? Подтягивал к минусу резистор 100ком. Никакие сигналы не проходят! Может конденсатор в этом случае нужно убрать? За ранее спасибо!
конденсатор не остановит переменный ток, можете убрать можете оставть.
Вот схема делителя.
Спасибо большое !Буду подключать и пробовать. Еще вопрос-Если берусь за минусовой провод рукой,то тоже показывает порядка 50гц! Это нормально или наводки?
bodriy2014, Отличные новости! А переменный резистор вовсе из схемы выбрасывается? За место него доп кнопок не будет?
bodriy2014,здравствуйте! Вопрос, обратил внимание,что при тестировании с генератора сигналов,если сигнал меньше 2 вольт,то частоту не считывает,то есть показывает ноль,хотя форма сигнала правильная! Можете как то пояснить с чем это связано?
Легко.
Частоту меряет апаратно с порта D5, и на цифровых портах все что ниже 1,8В считается нулем что выше еденица.(могу незначительно ошибиться смотрите даташит)
Он видит только нули.
То есть ничего не изменить,просто получается такая особенность осцилографа?
--Можно добавить на вход усилитель, например LM358 он до 20КГц сигнал не искажает.
--Можно считать частоту программно, мерять время и количество импульсов.
Да я также предположил,что на вход поставить операционный усилитель. А програмно измерять,то точность не изменится?
Зависит от того как реализовать подсчет.(от кода)
Причин ему считать не точно не вижу.
bodriy2014 добрый вечер! Сигнал до 2 вольт он не так и важен! Но как сделать с делителем ,чтобы онс 2в.- до 50 вольт воспринимал сигнал? Или так не получится?За ранее спасибо!
bodriy2014 добрый вечер! Сигнал до 2 вольт он не так и важен! Но как сделать с делителем ,чтобы онс 2в.- до 50 вольт воспринимал сигнал? Или так не получится?За ранее спасибо!
Да как сделать, руками я думаю)))
Без делителя он берет сигнал до 5В.
Если хотите до 50В собирайте щуп с делителем 1 к 10 и подключайте, можно продумать переключатель чтоб делитель переключать.
Но если делитель 1\10 то при 20 в и меньше на входе мк будет кокрас 2в. и меньше,то есть от 20 в и меньше снова будет мертвая зона! Единственное пока что я вижу это делать делители 1\2 , 1\5, 1\10 и т.д тогда будет перекрыватся мертвая зона на верхних пределах меньших делителей? Как вы считаете?
Не получается пререкроить под ST7781 (((
#include "TFTLCD.h" #define LCD_CS A3 #define LCD_CD A2 #define LCD_WR A1 #define LCD_RD A0 #define LCD_RESET A4 #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); //#include <Arial14.h> // font definitions #define txtLINE0 0 #define txtLINE1 16 #define txtLINE2 30 #define txtLINE3 46 const int LCD_WIDTH = 320; const int LCD_HEIGHT = 240; const int SAMPLES = 270; const int DOTS_DIV = 30; int sensorValue = 0; const int ad_sw = 3; // Analog 3 pin for switches const int ad_ch0 = 5; // Analog 6 pin for channel 0 const int ad_ch1 = 7; // Analog 7 pin for channel 1 const unsigned long VREF[] = {150, 300, 750, 1500, 3000}; // reference voltage 5.0V -> 150 : 1V/div range (100mV/dot) // It means 5.0 * DOTS_DIV = 150. Use 4.9 if reference voltage is 4.9[V] // -> 300 : 0.5V/div // -> 750 : 0.2V/div // ->1500 : 100mV/div // -> 3000 : 50mV/div const int MILLIVOL_per_dot[] = {33, 17, 6, 3, 2}; // mV/dot const int MODE_ON = 0; const int MODE_INV = 1; const int MODE_OFF = 2; const char *Modes[] = {" NORM", " INV", " OFF"}; const int TRIG_AUTO = 0; const int TRIG_NORM = 1; const int TRIG_SCAN = 2; const int TRIG_ONE = 3; const char *TRIG_Modes[] = {" Auto", " Norm", " Scan", " One"}; const int TRIG_E_UP = 0; const int TRIG_E_DN = 1; #define RATE_MIN 0 #define RATE_MAX 13 const char *Rates[] = {"F1-1", "F1-2 ", "F2 ", "5ms", "10ms", "20ms", "50ms", "0.1s", "0.2s", "0.5s", "1s", "2s", "5s", "10s"}; #define RANGE_MIN 0 #define RANGE_MAX 4 const char *Ranges[] = {"1V ", "0.5V", "0.2V", "0.1V", "50mV"}; unsigned long startMillis; byte data[4][SAMPLES]; // keep twice of the number of channels to make it a double buffer byte sample=0; // index for double buffer /////////////////////////////////////////////////////////////////////////////////////////////// // Define colors here #define BGCOLOR BLACK #define GRIDCOLOR WHITE #define CH1COLOR BLUE #define CH2COLOR GREEN // Declare variables and set defaults here // Note: only ch1 is available with Aitendo's parallel 320x240 TFT LCD byte range0 = RANGE_MIN, ch0_mode = MODE_ON; // CH0 short ch0_off = 204; byte range1 = RANGE_MIN, ch1_mode = MODE_ON; // CH1 short ch1_off = 204; byte rate = 3; // sampling rate byte trig_mode = TRIG_AUTO, trig_lv = 30, trig_edge = TRIG_E_UP, trig_ch = 1; // trigger settings byte Start = 1; // Start sampling byte menu = 0; // Default menu /////////////////////////////////////////////////////////////////////////////////////////////// void setup(){ tft.reset(); tft.initDisplay(); tft.setRotation(1); tft.fillScreen(BGCOLOR); tft.setTextColor(WHITE); tft.setTextSize(2); tft.setCursor(0, 0); tft.print("Arduino Oscillo Scope"); tft.setCursor(25, 100); tft.print("with Aitendo TFT LCD (320x240)"); tft.setCursor(75, 240); tft.print("(c) 2009-2014 non"); delay(2000); tft.fillScreen(BGCOLOR); Serial.begin(9600); DrawGrid(); DrawText(); } void CheckSW() { static unsigned long Millis = 0, oMillis = 0; unsigned long ms; unsigned short ain = analogRead(ad_sw); //Serial.println(ain); return; ms = millis(); if ((ms - Millis)<5) return; Millis = ms; oMillis = Millis; //Serial.println(ain); DrawText(); } void menu0_sw(int sw) { switch (sw) { case 0: // START/HOLD if (Start) Start = 0; else Start = 1; break; case 1: // CH0 RANGE - if (range0 < RANGE_MAX) range0 ++; break; case 2: // CH1 RANGE - if (range1 < RANGE_MAX) range1 ++; break; case 3: // RATE FAST if (rate > 0) rate --; break; case 4: // TRIG MODE if (trig_mode < TRIG_ONE) trig_mode ++; else trig_mode = 0; break; case 5: // SEND SendData(); break; case 6: // TRIG MODE if (trig_mode > 0) trig_mode --; else trig_mode = TRIG_ONE; break; case 7: // RATE SLOW if (rate < RATE_MAX) rate ++; break; case 8: // CH1 RANGE + if (range1 > 0) range1 --; break; case 9: // CH0 RANGE + if (range0 > 0) range0 --; break; case 10: default: // MENU SW menu ++; break; } } void SendData() { Serial.print(Rates[rate]); Serial.println("/div (30 samples)"); for (int i=0; i<SAMPLES; i ++) { Serial.print(data[sample + 0][i]*MILLIVOL_per_dot[range0]); Serial.print(" "); Serial.println(data[sample + 1][i]*MILLIVOL_per_dot[range1]); } } void DrawGrid() { for (int x=0; x<=SAMPLES; x += 2) { // Horizontal Line for (int y=0; y<=LCD_HEIGHT; y += DOTS_DIV) { tft.drawPixel(x, y, GRIDCOLOR); CheckSW(); } if (LCD_HEIGHT == 240) tft.drawPixel(x, LCD_HEIGHT-1, GRIDCOLOR); } for (int x=0; x<=SAMPLES; x += DOTS_DIV ) { // Vertical Line for (int y=0; y<=LCD_HEIGHT; y += 2) { tft.drawPixel(x, y, GRIDCOLOR); CheckSW(); } } } void DrawText() { tft.setTextColor(YELLOW); tft.setTextSize(1); tft.setCursor(SAMPLES+3, 5); tft.print(Ranges[range1]); tft.println("/DIV"); tft.setCursor(SAMPLES+3, 15); tft.print(Rates[rate]); tft.println("/DIV"); tft.setCursor(SAMPLES+3, 25); tft.println(TRIG_Modes[trig_mode]); tft.setCursor(SAMPLES+3, 35); tft.println(trig_edge == TRIG_E_UP ? "UP" : "DN"); tft.setCursor(SAMPLES+3, 45); tft.println(Modes[ch1_mode]); tft.setCursor(SAMPLES+3, 60); tft.setTextColor(RED); tft.println(" 5 V"); tft.setCursor(SAMPLES+3, 90); tft.println(" 4 V"); tft.println(""); tft.setCursor(SAMPLES+3, 120); tft.println(" 3 V"); tft.println(""); tft.setCursor(SAMPLES+3, 150); tft.println(" 2 V"); tft.println(""); tft.setCursor(SAMPLES+3, 180); tft.println(" 1 V"); tft.println(""); tft.setCursor(SAMPLES+3, 210); tft.println(" 0 V"); // tft.setCursor(SAMPLES, 70); // tft.println(trig_ch == 0 ? "T:1" : "T:2"); } void DrawGrid(int x) { if ((x % 2) == 0) for (int y=0; y<=LCD_HEIGHT; y += DOTS_DIV) tft.drawPixel(x, y, GRIDCOLOR); if ((x % DOTS_DIV) == 0) for (int y=0; y<=LCD_HEIGHT; y += 2) tft.drawPixel(x, y, GRIDCOLOR); } void ClearAndDrawGraph() { int clear = 0; if (sample == 0) clear = 2; #if 0 for (int x=0; x<SAMPLES; x++) { GLCD.SetDot(x, LCD_HEIGHT-data[clear+0][x], WHITE); GLCD.SetDot(x, LCD_HEIGHT-data[clear+1][x], WHITE); GLCD.SetDot(x, LCD_HEIGHT-data[sample+0][x], BLACK); GLCD.SetDot(x, LCD_HEIGHT-data[sample+1][x], BLACK); } #else for (int x=0; x<(SAMPLES-1); x++) { tft.drawLine(x, LCD_HEIGHT-data[clear+0][x], x+1, LCD_HEIGHT-data[clear+0][x+1], BGCOLOR); tft.drawLine(x, LCD_HEIGHT-data[clear+1][x], x+1, LCD_HEIGHT-data[clear+1][x+1], BGCOLOR); if (ch0_mode != MODE_OFF) tft.drawLine(x, LCD_HEIGHT-data[sample+0][x], x+1, LCD_HEIGHT-data[sample+0][x+1], CH1COLOR); if (ch1_mode != MODE_OFF) tft.drawLine(x, LCD_HEIGHT-data[sample+1][x], x+1, LCD_HEIGHT-data[sample+1][x+1], CH2COLOR); CheckSW(); } #endif } void ClearAndDrawDot(int i) { int clear = 0; if (i <= 1) return; if (sample == 0) clear = 2; #if 0 for (int x=0; x<SAMPLES; x++) { GLCD.SetDot(x, LCD_HEIGHT-data[clear+0][x], WHITE); GLCD.SetDot(x, LCD_HEIGHT-data[clear+1][x], WHITE); GLCD.SetDot(x, LCD_HEIGHT-data[sample+0][x], BLACK); GLCD.SetDot(x, LCD_HEIGHT-data[sample+1][x], BLACK); } #else tft.drawLine(i-1, LCD_HEIGHT-data[clear+0][i-1], i, LCD_HEIGHT-data[clear+0][i], BGCOLOR); tft.drawLine(i-1, LCD_HEIGHT-data[clear+1][i-1], i, LCD_HEIGHT-data[clear+1][i], BGCOLOR); if (ch0_mode != MODE_OFF) tft.drawLine(i-1, LCD_HEIGHT-data[sample+0][i-1], i, LCD_HEIGHT-data[sample+0][i], CH1COLOR); if (ch1_mode != MODE_OFF) tft.drawLine(i-1, LCD_HEIGHT-data[sample+1][i-1], i, LCD_HEIGHT-data[sample+1][i], CH2COLOR); #endif DrawGrid(i); } void DrawGraph() { for (int x=0; x<SAMPLES; x++) { tft.drawPixel(x, LCD_HEIGHT-data[sample+0][x], CH1COLOR); tft.drawPixel(x, LCD_HEIGHT-data[sample+1][x], CH2COLOR); } } void ClearGraph() { int clear = 0; if (sample == 0) clear = 2; for (int x=0; x<SAMPLES; x++) { tft.drawPixel(x, LCD_HEIGHT-data[clear+0][x], BGCOLOR); tft.drawPixel(x, LCD_HEIGHT-data[clear+1][x], BGCOLOR); } } inline unsigned long adRead(byte ch, byte mode, int off) { unsigned long a = analogRead(ch); a = ((a+off)*VREF[ch == ad_ch0 ? range0 : range1]+512) >> 10; a = a>=(LCD_HEIGHT+1) ? LCD_HEIGHT : a; if (mode == MODE_INV) return LCD_HEIGHT - a; return a; } void loop() { if (trig_mode != TRIG_SCAN) { unsigned long st = millis(); byte oad; if (trig_ch == 0) oad = adRead(ad_ch0, ch0_mode, ch0_off); else oad = adRead(ad_ch1, ch1_mode, ch1_off); for (;;) { byte ad; if (trig_ch == 0) ad = adRead(ad_ch0, ch0_mode, ch0_off); else ad = adRead(ad_ch1, ch1_mode, ch1_off); if (trig_edge == TRIG_E_UP) { if (ad >= trig_lv && ad > oad) break; } else { if (ad <= trig_lv && ad < oad) break; } oad = ad; CheckSW(); if (trig_mode == TRIG_SCAN) break; if (trig_mode == TRIG_AUTO && (millis() - st) > 100) break; } } // sample and draw depending on the sampling rate if (rate <= 5 && Start) { // change the index for the double buffer if (sample == 0) sample = 2; else sample = 0; if (rate == 0) { // full speed, channel 0 only unsigned long st = millis(); for (int i=0; i<SAMPLES; i ++) { data[sample+0][i] = adRead(ad_ch0, ch0_mode, ch0_off); } for (int i=0; i<SAMPLES; i ++) data[sample+1][i] = 0; // Serial.println(millis()-st); } else if (rate == 1) { // full speed, channel 1 only unsigned long st = millis(); for (int i=0; i<SAMPLES; i ++) { data[sample+1][i] = adRead(ad_ch1, ch1_mode, ch1_off); } for (int i=0; i<SAMPLES; i ++) data[sample+0][i] = 0; // Serial.println(millis()-st); } else if (rate == 2) { // full speed, dual channel unsigned long st = millis(); for (int i=0; i<SAMPLES; i ++) { data[sample+0][i] = adRead(ad_ch0, ch0_mode, ch0_off); data[sample+1][i] = adRead(ad_ch1, ch1_mode, ch1_off); } // Serial.println(millis()-st); } else if (rate >= 3 && rate <= 5) { // .5ms, 1ms or 2ms sampling const unsigned long r_[] = {5000/DOTS_DIV, 10000/DOTS_DIV, 20000/DOTS_DIV}; unsigned long st0 = millis(); unsigned long st = micros(); unsigned long r = r_[rate - 3]; for (int i=0; i<SAMPLES; i ++) { while((st - micros())<r) ; st += r; data[sample+0][i] = adRead(ad_ch0, ch0_mode, ch0_off); data[sample+1][i] = adRead(ad_ch1, ch1_mode, ch1_off); } // Serial.println(millis()-st0); } ClearAndDrawGraph(); CheckSW(); DrawGrid(); DrawText(); } else if (Start) { // 5ms - 500ms sampling // copy currently showing data to another if (sample == 0) { for (int i=0; i<SAMPLES; i ++) { data[2][i] = data[0][i]; data[3][i] = data[1][i]; } } else { for (int i=0; i<SAMPLES; i ++) { data[0][i] = data[2][i]; data[1][i] = data[3][i]; } } const unsigned long r_[] = {50000/DOTS_DIV, 100000/DOTS_DIV, 200000/DOTS_DIV, 500000/DOTS_DIV, 1000000/DOTS_DIV, 2000000/DOTS_DIV, 5000000/DOTS_DIV, 10000000/DOTS_DIV}; unsigned long st0 = millis(); unsigned long st = micros(); for (int i=0; i<SAMPLES; i ++) { while((st - micros())<r_[rate-6]) { CheckSW(); if (rate<6) break; } if (rate<6) { // sampling rate has been changed tft.fillScreen(BGCOLOR); break; } st += r_[rate-6]; if (st - micros()>r_[rate-6]) st = micros(); // sampling rate has been changed to shorter interval if (!Start) { i --; continue; } data[sample+0][i] = adRead(ad_ch0, ch0_mode, ch0_off); data[sample+1][i] = adRead(ad_ch1, ch1_mode, ch1_off); ClearAndDrawDot(i); } // Serial.println(millis()-st0); DrawGrid(); DrawText(); } else { CheckSW(); } if (trig_mode == TRIG_ONE) Start = 0; }Но надписи перед самой сеткой почему то в самом верху экрана и не видны
-
Всем привет!
В свободное время доработал Пультоскоп!
Было так- https://youtu.be/OuyTVQXz458
Это еще не финал, но уже видно что он подрос стал на голову быстрее и дружелюбнее.
Рендерится звук и заливается на ютуб.
Сегодня выложу видео.
Превью обновленного прибора.
https://youtu.be/PFWsIGPIeac
Здорово получается. А как он справляется с изменяющимся сигналом имеющим несколько гармоник? В нём нет синхронизации, она будет реализована паузой, записью определённого количества выборок и её отображением на дисплей с возможностью сдвига в обе стороны для просмотра? Хотелось бы увидеть на видео изменяющийся сигнал с гармониками и на верхнем пределе возможности, тоесть увеличивать частоту отображаемого сигнала, растяжку его по времени. Вещь замечательная, для тех кто занимается чисто Ардуино или вообще низкочастотными цифровыми сигналами, как переносной логический проник.
Gres Привет!
Перед тем как отвечать скажу сразу, хорошие вопросы мне обычно подсказывают как и что улучшить!)
Теперь по рядку
--Для него самой тяжело отображаемый сигнал это меандр, все что имеет скругленные форму может отображаться на более высоких частотах.Гармоники покажу на следующем видео.
--Синхронизацию могу реализовать пока только програмно, запись данных в буфер и отображение буфера с учетом оной. Пауза будет только замораживать отображение без прокрутки, кнопками будем листать не буфер в зад и вперед, а заново его наполнять. Если будет работать неудобно изменю.
--Тест верхних пределов будет в следующем видео в разогнанном состоянии и в стоковом.
Пока доступна полоса пропускания в стоке 300К и в разгоне 600К. Очень хочется реализовать эфект стробоскопа чтоб увеличить полосу пропускания до 8МГц, пробовал по быстрому написать не получилось((
Отличный прибор получается!Буду следить,обязательно за ходом разработки.Такой прибор очень нужен.Пока буду использовать на экране 5110.Автор-спасибо огромное за труды!!!!
Очень понравился приборчик! Ждем с нетерпением публикации.
Автору УВАЖУХА!!!
bodriy2014, привет! Отличный прибор получается. Четкие задачи, выполнение на высоком уровне! Скажи какие компоненты сейчас ипользуются, чтоб можно было потихоньку прикупать. То идти они могут очень долго. Arduino 5ти вольтовая? Питание сам делал или модуль? Экран любой определенного разрешения или конкретная модель? Какая? О чем еще нужно заранее позаботиться?
Jtest Привет.
--Ардуино 5В любая с микроконтроллером Atmega328(uno,nano,pro mini) и большим кварцем чтоб можно было выпаять.
--дисплей у меня TFT 2.4 дюйма 240*320 на контроллере spfd5408 купил у местного перекупа чтоб не ждать.
--буду делать доп. версию для дисплея 5110/3310 их у меня много и каждый сможет найти легко себе такой.
--хорошо прокоментирую код чтоб могли себе менять под любые дисплеи.
По питание каждый пусть себе сам выбирает модуль готовый или напрямую от USB, то что я впихнул покажу в видео.
bodriy2014, Да... планов настроенно!)) Удачи в их реализации! Я пока прикуплю ардуинку, может чего с дисплеем решу (есть в наличии китайские телефоны с дисплеями такого разрешения, нужно выяснить на каких контроллерах они работают).
bodriy2014, приветствую Вас. Респект Вам за проделанную работу. А новый экранчик у Вас вроде бы сенсорный, отчего же решили управление кнопочками делать?