Доброго времени суток всем!
Накопал в сети интересный девайс -осциллограф на ARDUINO.
У меня как раз завалялись дома Arduino Pro Mini 328 - 3.3V/8MHz и графический LCD дисплей Nokia 5110 для Arduino

залил этот скетч:
11 | #include <Adafruit_GFX.h> |
12 | #include <Adafruit_PCD8544.h> |
19 | Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3); |
23 | static unsigned char __attribute__ ((progmem)) logo16_glcd_bmp[]={ |
24 | 0x06, 0x0D, 0x29, 0x22, 0x66, 0x24, 0x00, 0x01, 0x87, 0x00, 0x27, 0x6C, 0x20, 0x23, 0x06, 0x00, |
25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; |
26 | #define LOGO16_GLCD_HEIGHT 16 |
27 | #define LOGO16_GLCD_WIDTH 16 |
47 | display.setContrast(40); |
49 | display.clearDisplay(); |
54 | delayVariable = analogRead(scaleYAI); |
55 | delayVariable = (delayVariable/50); |
56 | xVariable = analogRead(scaleXAI); |
57 | xVariable = (xVariable/22); |
59 | for (yCtr = 0; yCtr < 85; yCtr += 1) |
61 | posy = analogRead(channelAI); |
62 | myArray[yCtr] = (posy/xVariable); |
63 | delay (delayVariable); |
67 | display.clearDisplay(); |
69 | for (yCtr = 0; yCtr < 85; yCtr += 1) |
71 | display.drawPixel(yCtr, myArray[yCtr], BLACK); |
Подключил дисплей как на картинке
все заработало, но на экране нет ни частоты ни амплитуды
Порылся еще в сети и нарыл осциллограф с другим экраном от NOKIA 3310
Но тут уже все отображается и частота и амплитуда
скетч:
005 | byte useThreshold = 1; |
006 | byte theThreshold = 128; |
007 | unsigned int timePeriod = 200; |
008 | byte voltageRange = 1; |
009 | byte ledBacklight = 100; |
011 | boolean autoHScale = true ; |
012 | boolean linesNotDots = true ; |
015 | const byte vTextShift = 3; |
016 | const byte numOfSamples = 100; |
017 | unsigned int HQadcReadings[numOfSamples]; |
018 | byte adcReadings[numOfSamples]; |
019 | byte thresLocation = 0; |
020 | float voltageConst = 0.052381; |
027 | const byte theAnalogPin = 7; |
029 | const byte lcdLED = 6; |
031 | const byte lcdRESET = 8; |
033 | const byte lcdMOSI = 11; |
034 | const byte lcdSCK = 13; |
039 | U8GLIB_MINI12864 u8g(lcdSCK, lcdMOSI, lcdCS, lcdA0, lcdRESET); |
046 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) |
049 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) |
052 | void collectData( void ) { |
053 | unsigned int tempThres = 0; |
056 | if (autoHScale == true ) { |
059 | if (thresLocation > 5*numOfSamples/8) { |
060 | timePeriod = timePeriod + 10; |
061 | } else if (thresLocation < 3*numOfSamples/8) { |
062 | timePeriod = timePeriod - 10; |
063 | } else if (thresLocation > numOfSamples/2) { |
064 | timePeriod = timePeriod + 2; |
065 | } else if (thresLocation < numOfSamples/2) { |
066 | timePeriod = timePeriod - 2; |
070 | if (timePeriod < 35) { |
075 | if (voltageRange == 1) { |
076 | voltageConst = 0.0523810; |
077 | } else if (voltageRange == 2) { |
078 | voltageConst = 0.0261905; |
079 | } else if (voltageRange == 3) { |
080 | voltageConst = 0.0130952; |
084 | if (voltageRange == 1) tempThres = theThreshold << 2; |
085 | else if (voltageRange == 2) tempThres = theThreshold << 1; |
086 | else if (voltageRange == 3) tempThres = theThreshold; |
087 | if (useThreshold == 1) { |
088 | i = 0; while ((analogRead(theAnalogPin)>tempThres) && (i<32768)) i++; |
089 | i = 0; while ((analogRead(theAnalogPin)<tempThres) && (i<32768)) i++; |
091 | else if (useThreshold == 2) { |
092 | i = 0; while ((analogRead(theAnalogPin)<tempThres) && (i<32768)) i++; |
093 | i = 0; while ((analogRead(theAnalogPin)>tempThres) && (i<32768)) i++; |
097 | for (i=0; i<numOfSamples; i++) { |
099 | HQadcReadings[i] = analogRead(theAnalogPin); |
101 | delayMicroseconds(timePeriod-35); |
103 | for (i=0; i<numOfSamples; i++) { |
105 | if (voltageRange == 1) { |
106 | if (HQadcReadings[i]>>4 < 0b111111) adcReadings[i] = HQadcReadings[i]>>4 & 0b111111; |
107 | else adcReadings[i] = 0b111111; |
108 | } else if (voltageRange == 2) { |
109 | if (HQadcReadings[i]>>3 < 0b111111) adcReadings[i] = HQadcReadings[i]>>3 & 0b111111; |
110 | else adcReadings[i] = 0b111111; |
111 | } else if (voltageRange == 3) { |
112 | if (HQadcReadings[i]>>2 < 0b111111) adcReadings[i] = HQadcReadings[i]>>2 & 0b111111; |
113 | else adcReadings[i] = 0b111111; |
116 | adcReadings[i] = 63-adcReadings[i]; |
120 | if (useThreshold != 0) { |
121 | if (useThreshold == 1) { |
123 | while ((adcReadings[thresLocation]<(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++); |
125 | while ((adcReadings[thresLocation]>(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++); |
127 | else if (useThreshold == 2) { |
129 | while ((adcReadings[thresLocation]>(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++); |
131 | while ((adcReadings[thresLocation]<(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++); |
134 | theFreq = ( float ) 1000/(thresLocation * timePeriod) * 1000; |
139 | for (i=0; i<numOfSamples; i++) |
140 | avgV = avgV + adcReadings[i]; |
141 | avgV = (63-(avgV / numOfSamples)) * voltageConst; |
145 | for (i=0; i<numOfSamples; i++) |
146 | if (adcReadings[i]<maxV) maxV = adcReadings[i]; |
147 | maxV = (63-maxV) * voltageConst; |
151 | for (i=0; i<numOfSamples; i++) |
152 | if (adcReadings[i]>minV) minV = adcReadings[i]; |
153 | minV = (63-minV) * voltageConst; |
159 | void handleSerial( void ) { |
162 | boolean exitLoop = false ; |
166 | inByte = Serial .read(); |
167 | } while ( Serial .available() > 0); |
169 | Serial .print( "\nArduino LCD Oscilloscope\n" ); |
170 | Serial .print( " 1 - Change threshold usage (currently: " ); |
171 | if (useThreshold == 0) Serial .print( "Off)\n" ); |
172 | else if (useThreshold == 1) Serial .print( "Rise)\n" ); |
173 | else if (useThreshold == 2) Serial .print( "Fall)\n" ); |
174 | Serial .print( " 2 - Change threshold value (currently: " ); |
175 | Serial .print(theThreshold, DEC); Serial .print( ")\n" ); |
176 | Serial .print( " 3 - Change sampling period (currently: " ); |
177 | Serial .print(timePeriod, DEC); Serial .print( ")\n" ); |
178 | Serial .print( " 4 - Change voltage range (currently: " ); |
179 | if (voltageRange == 1) Serial .print( "0-3.3V)\n" ); |
180 | else if (voltageRange == 2) Serial .print( "0-1.65V)\n" ); |
181 | else if (voltageRange == 3) Serial .print( "0-0.825V)\n" ); |
182 | Serial .print( " 5 - Toggle auto horizontal (time) scaling (currently: " ); |
183 | if (autoHScale == true ) Serial .print( "On)\n" ); |
184 | else if (autoHScale == false ) Serial .print( "Off)\n" ); |
185 | Serial .print( " 6 - Toggle line/dot display (currently: " ); |
186 | if (linesNotDots == true ) Serial .print( "Lines)\n" ); |
187 | else if (linesNotDots == false ) Serial .print( "Dots)\n" ); |
188 | Serial .print( " 8 - Exit\n" ); |
195 | do { draw(); } while ( u8g.nextPage() ); |
196 | } while ( Serial .available() == 0); |
197 | inByte = Serial .read(); |
200 | Serial .print( "Change threshold usage\n" ); |
201 | Serial .print( " 0 - Off\n" ); |
202 | Serial .print( " 1 - Rise\n" ); |
203 | Serial .print( " 2 - Fall\n" ); |
204 | do { } while ( Serial .available() == 0); |
205 | dataByte = Serial .read(); |
206 | if (dataByte == '0' ) useThreshold = 0; |
207 | else if (dataByte == '1' ) useThreshold = 1; |
208 | else if (dataByte == '2' ) useThreshold = 2; |
209 | } else if (inByte == '2' ) { |
210 | Serial .print( "Change threshold value (thresholds for 0-3.3V,0-1.65V,0-0.825V ranges)\n" ); |
211 | Serial .print( " 0 - 32 (0.41V, 0.21V, 0.10V)\n" ); |
212 | Serial .print( " 1 - 80 (1.04V, 0.52V, 0.26V)\n" ); |
213 | Serial .print( " 2 - 128 (1.66V, 0.83V, 0.41V)\n" ); |
214 | Serial .print( " 3 - 176 (2.28V, 1.14V, 0.57V)\n" ); |
215 | Serial .print( " 4 - 224 (2.90V, 1.45V, 0.72V)\n" ); |
216 | do { } while ( Serial .available() == 0); |
217 | dataByte = Serial .read(); |
218 | if (dataByte == '0' ) theThreshold = 32; |
219 | else if (dataByte == '1' ) theThreshold = 80; |
220 | else if (dataByte == '2' ) theThreshold = 128; |
221 | else if (dataByte == '3' ) theThreshold = 176; |
222 | else if (dataByte == '4' ) theThreshold = 224; |
223 | } else if (inByte == '3' ) { |
224 | Serial .print( "Change sampling frequency\n" ); |
225 | Serial .print( " 0 - 28 kHz (35 us/sample)\n" ); |
226 | Serial .print( " 1 - 20 kHz (50 us/sample)\n" ); |
227 | Serial .print( " 2 - 10 kHz (100 us/sample)\n" ); |
228 | Serial .print( " 3 - 5 kHz (200 us/sample)\n" ); |
229 | Serial .print( " 4 - 2.5 kHz (400 us/sample)\n" ); |
230 | do { } while ( Serial .available() == 0); |
231 | dataByte = Serial .read(); |
232 | if (dataByte == '0' ) timePeriod = 35; |
233 | else if (dataByte == '1' ) timePeriod = 50; |
234 | else if (dataByte == '2' ) timePeriod = 100; |
235 | else if (dataByte == '3' ) timePeriod = 200; |
236 | else if (dataByte == '4' ) timePeriod = 400; |
237 | } else if (inByte == '4' ) { |
238 | Serial .print( "Change voltage range\n" ); |
239 | Serial .print( " 1 - 0-3.3V\n" ); |
240 | Serial .print( " 2 - 0-1.65V\n" ); |
241 | Serial .print( " 3 - 0-0.825V\n" ); |
242 | do { } while ( Serial .available() == 0); |
243 | dataByte = Serial .read(); |
244 | if (dataByte == '1' ) voltageRange = 1; |
245 | else if (dataByte == '2' ) voltageRange = 2; |
246 | else if (dataByte == '3' ) voltageRange = 3; |
247 | } else if (inByte == '5' ) { |
248 | Serial .print( "Toggle auto horizontal (time) scaling\n" ); |
249 | Serial .print( " 0 - Off\n" ); |
250 | Serial .print( " 1 - On\n" ); |
251 | do { } while ( Serial .available() == 0); |
252 | dataByte = Serial .read(); |
253 | if (dataByte == '0' ) autoHScale = false ; |
254 | else if (dataByte == '1' ) autoHScale = true ; |
255 | } else if (inByte == '6' ) { |
256 | Serial .print( "Toggle line/dot display\n" ); |
257 | Serial .print( " 0 - Lines\n" ); |
258 | Serial .print( " 1 - Dots\n" ); |
259 | do { } while ( Serial .available() == 0); |
260 | dataByte = Serial .read(); |
261 | if (dataByte == '0' ) linesNotDots = true ; |
262 | else if (dataByte == '1' ) linesNotDots = false ; |
263 | } else if (inByte == '8' ) { |
264 | Serial .print( "Bye!\n" ); |
267 | } while (exitLoop == false ); |
274 | u8g.setFont(u8g_font_micro); |
277 | u8g.drawStr(0, 5+vTextShift, "Av" ); |
278 | u8g.drawStr(0, 11+vTextShift, "Mx" ); |
279 | u8g.drawStr(0, 17+vTextShift, "Mn" ); |
280 | u8g.drawStr(0, 23+vTextShift, "PP" ); |
281 | u8g.drawStr(0, 29+vTextShift, "Th" ); |
282 | u8g.drawStr(24, 35+vTextShift, "V" ); |
283 | u8g.drawStr(0, 41+vTextShift, "Tm" ); |
284 | u8g.drawStr(4, 47+vTextShift, "ms/div" ); |
285 | u8g.drawStr(20, 53+vTextShift, "Hz" ); |
286 | u8g.drawStr(0, 59+vTextShift, "R" ); |
289 | if (autoHScale == true ) u8g.drawStr(124, 5, "A" ); |
290 | dtostrf(avgV, 3, 2, buffer); |
291 | u8g.drawStr(12, 5+vTextShift, buffer); |
292 | dtostrf(maxV, 3, 2, buffer); |
293 | u8g.drawStr(12, 11+vTextShift, buffer); |
294 | dtostrf(minV, 3, 2, buffer); |
295 | u8g.drawStr(12, 17+vTextShift, buffer); |
296 | dtostrf(ptopV, 3, 2, buffer); |
297 | u8g.drawStr(12, 23+vTextShift, buffer); |
298 | dtostrf(theFreq, 5, 0, buffer); |
299 | u8g.drawStr(0, 53+vTextShift, buffer); |
300 | if (useThreshold == 0) { |
301 | u8g.drawStr(12, 29+vTextShift, "Off" ); |
302 | } else if (useThreshold == 1) { |
303 | u8g.drawStr(12, 29+vTextShift, "Rise" ); |
304 | dtostrf(( float ) (theThreshold>>2) * voltageConst, 3, 2, buffer); |
305 | } else if (useThreshold == 2) { |
306 | u8g.drawStr(12, 29+vTextShift, "Fall" ); |
307 | dtostrf(( float ) (theThreshold>>2) * voltageConst, 3, 2, buffer); |
309 | u8g.drawStr(8, 35+vTextShift, buffer); |
311 | if (timePeriod < 400) { |
312 | dtostrf(( float ) timePeriod/1000 * 25, 3, 2, buffer); |
313 | } else if (timePeriod < 4000) { |
314 | dtostrf(( float ) timePeriod/1000 * 25, 3, 1, buffer); |
315 | } else if (timePeriod < 40000) { |
316 | dtostrf(( float ) timePeriod/1000 * 25, 3, 0, buffer); |
318 | dtostrf(( float ) 0.00, 3, 2, buffer); |
320 | u8g.drawStr(12, 41+vTextShift, buffer); |
321 | if (voltageRange == 1) { |
322 | u8g.drawStr(4, 59+vTextShift, "0-3.30" ); |
323 | } else if (voltageRange == 2) { |
324 | u8g.drawStr(4, 59+vTextShift, "0-1.65" ); |
325 | } else if (voltageRange == 3) { |
326 | u8g.drawStr(4, 59+vTextShift, "0-0.83" ); |
330 | u8g.drawLine((128-numOfSamples),0,(128-numOfSamples),63); |
331 | if (useThreshold != 0) |
332 | for (i=29; i<127; i+=3) |
333 | u8g.drawPixel(i,63-(theThreshold>>2)); |
334 | for (i=0; i<63; i+=5) { |
337 | u8g.drawPixel(103,i); |
338 | u8g.drawPixel(127,i); |
341 | for (i=0; i<63; i+=3) |
342 | u8g.drawPixel(thresLocation+(128-numOfSamples),i); |
344 | if (linesNotDots == true ) { |
345 | for (i=1; i<numOfSamples; i++) |
346 | u8g.drawLine(i+(128-numOfSamples)-1,adcReadings[i-1],i+(128-numOfSamples),adcReadings[i]); |
348 | for (i=2; i<numOfSamples; i++) |
349 | u8g.drawPixel(i+(128-numOfSamples),adcReadings[i]); |
358 | analogWrite(lcdLED, ledBacklight); |
373 | do { draw(); } while ( u8g.nextPage() ); |
376 | if ( Serial .available() > 0) { |
Если кто знает как переделать этот скетч c NOKIA 3310

const byte lcdLED = 6; // LED Backlight
const byte lcdA0 = 7; // Data and command selections. L: command H : data
const byte lcdRESET = 8; // Low reset
const byte lcdCS = 9; // SPI Chip Select (internally pulled up), active low
const byte lcdMOSI = 11; // SPI Data transmission
const byte lcdSCK = 13; // SPI Serial Clock
под мой экран NOKIA 5110

// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Помогите разобраться, я уже себе весь мозг проел
вот так этот девайс должен работать
http://semifluid.com/wp-content/uploads/2013/05/MVI_4205.mp4.mp4
U8GLIB универсальная библиотека вроде как)
При беглом осмотре, в 66 строке yCtr == 0; // set the counter to zero so we can use it
Может там должно быть присваивание?
Не имеет значения, следом идет цикл который сбросит в 0. Строка ничего не делает полезного или вредного.
Ключевое - это заменить U8GLIB_MINI12864 на U8GLIB_PCD8544
1
const
byte
lcdLED = 6;
// LED Backlight
2
const
byte
lcdA0 = 7;
// D/C - Data and command selections. L: command H : data
3
const
byte
lcdRESET = 8;
// RST- Low reset
4
const
byte
lcdCS = 9;
// SCE - SPI Chip Select (internally pulled up), active low
5
const
byte
lcdMOSI = 11;
// DIN(MOSI) - SPI Data transmission
6
const
byte
lcdSCK = 13;
// SCK - SPI Serial Clock
а вот дальше начинаются проблемы, что разрешение экрана меньше чем надо :(
На фото дисплей 5110 с последней программой, а на дуине замкнут adc7 с d0(rx), таким образом на вход осцилографа подается сигнал с uart'а, куда бегут с компа буковки "а".
Был у меня дисплейчик побольше и за ту же цену, что 5110, см. http://we.easyelectronics.ru/lcd_gfx/podklyuchenie-tft-displeya-k-avr.html
Дисплей больше разрешением, даже чем тот, что в оригинальном примере, да еще и цветной. Правда ардуинка слишком медленно расчеты делает для вывода на экран, пришлось весь вывод на экран значительно переработать, стало приемлимо и красиво :) На экране ШИМ подсветки этого же дисплея.
Если кому понадобится, выложу код для данного дисплея.
Сегодня приобрел вот такой экранчик:
По первой Вашей ссылке подключение. Передача данных по 8бит D0-D7. Последовательность инициализаци надо искать в даташите. Далее надо экспериментировать. В основном все покупают для подобных поделок дисплеи уже на плате с простым интерфейсом spi, а поскольку сразу все делают так, то и инфы на такие дисплеи больше.
Я даже не задумывался, что возникнут такие сложности в подключении этого дисплея.
для подключения этого дисплея нужно применить ету схему? Я правильно понял?
1
//U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
Вариант Вы написали правильно, вот только Ваш дисплей в Возможно совместимых с данной библиотекой.
Есть вот такая темка http://forum.arduino.cc/index.php/topic,134689.0.html - может чем поможет.
у меня для такого подключения не хватит ног на ардуине
почему не хватит? хватает же
Если не трудно напишина какие ноги этот экран мне подключать? Там ведь есть и 16, 17,18 но на моей дуине такого нет((
пины можно любые настроить для доп. управляющих. для основных из одного порта должно быть. тоесть оставляете как есть
а вот 16 17 18 меняете на свои
я бы так сделал. как в либе сделано надо смотреть
попробуйте проще. меняете на любые доступные и проверьте.
я не нашел соответствия одному порту на меге328 и 2560 для выводов данных. может и проглядел, но лучше проверье тупо вставляя свои пины
Идеально d0-d7 подключить целиком на 1 порт atmega, а остальные любые, ну кроме тех, что используются. Кстати, так и передача данных будет быстрее, чем по spi. Если ардуино на меге вроде 328-й то целиком ни одного порта не получается: на PORTB сидит кварц, на С находится ADC, на D сидит UART, т.е. для идеала надо что-то более многоногое :(
Пинов должно хватить в любом случае. Только лучше базовый доступ к дисплею свой делать. Кстати, под переделку лучше использовать библиотеку adafruit, там на, мой взгляд, понятнеее что переписывать надо. Собственно, я на нее все и переделал себе, плюс немного оптимизации и получилось очень даже ничего :)
Еще немного и я разобью этот дисплей об ету ардуину.
Хоть как то бы подключить уже. Я уже задолбался, мозг пухнет
С таким подходом у Вас ничего не получится :(
С первого раза редко, что получается. Почитайте обсуждения профессионалов, которые говорят: подозрительно, что у меня все сразу заработало.
Поэтому самое оптимальное брать примеры, которые заведомо работают и повторять их. Для этого Вам надо для начала, прикупить дисплей, на который есть готовые примеры, а потом уже данный мучать, со знанием дела...
Это у меня от того что я в тупик уткнулся, эмоции полезли мучать этот дисплей я то буду пока у меня не получится. Решил подключать по 8 бит, пока перепаял все провода, потом подключил и не чего не произошло. Дисплей как лежал без признаков жизни так и продолжал спокойно лежать. Я до трех часов ночи издевался над гуглом и над дисплеем, пока сам не выключился
Там на дисплее, как оказалось еще перемычка есть. Последовательный или паралельный
Давайте переключим на последовательный режим и тогда ему будет соответствовать один из методов подключения ST7565
Значит 17 и 18 - это подсветка дисплея: Земля и питание(3.3В). Без подсветкы Вы врятли чего увидите на экране. На моем не видно ничего.
1 - GND
2 - VCC (3.3В)
6 - D/C
17 - sclk
16 - MOSI
5 - CS - chip select
4 - reset
Более детально см. тут http://www.crystalfontz.com/controllers/Novatek_NT7534.pdf
UPD. Есть предположение, что заработает вот такой класс U8GLIB_NHD_C12864
Вот спасибо за помощь. Хоть какой то сдвиг в этом деле. Я в тупик уже залез, не знал уже что дальше делать. Все идеи закончились. Сегодня приеду с работы домой, Сразу попробую подключить, так как вы написали.
Еще дополнение:
U8GLIB_NHD_C12864(sck, mosi, cs, a0 [, reset]) - Вариант SW SPI - програмный SPI
U8GLIB_NHD_C12864(cs, a0 [, reset]) - Вариант HW SPI - Хардварный. Разумеется - это лучше, потому как быстрее, только SCLK и MOSI подключаются строго на 11-й и 13-й пины дудки, см. примеры.
RESET - необязателен, его можно замкнуть с ресетом дуинки.
подключил так, как вы написали. Не заработало (
Кто то не правильный или ардуинка или дисплей или я))
Завтра с самого утра займусь с начала проверять все что наподключал. Где то должен быть какой то косяк. Ардуинку проверял только что на дисплее от 5110 - все работает. Вот только заметил какие то крадковременные подвисания при работе программы осциллографа. может они и ранее были а я не замечал их.
Подключение пинов я написал как написано в даташите. Мог пропустить какую-то деталь. Потом класс из библиотеки u8glib, совместим условно с Вашим дисплеем и может не стартовать из-за какой-нибудь пропущенной мелочи в инициализации, или может Вы пины на шлейфе не в ту сторону нумировали? Режим точно последовательный включили? Я в свое время долго мучал протокол ps/2 где в зависимости от компа идет разная инициализация устройства и если все не предусмотреть, то ничего и не работает и непонятно куда девается "искра внутреннего сгорания", потом все-таки нашел...
Подвисания и должны быть. Между обновлениями дисплея он делает всю пачку измерений. Если масштаб используется для высокой частоты, то измерения делаются без задержек, если низкой частоты, то чтобы не отображать одну прямую, делаются искуственные задержки между измерениями, вот и получается весьма заметная задержка.
А при неправильной библиотеке на экране должно что то появляться? Просто сколько я не экспериментировал, диспей лежит без всяких признаков жизни, кроме подсветки
Чтобы что-то изменилось, нужна правильная последовательность инициализации. Если выбран неверно метод, дисплей не заработает. Надо курить внимательно даташит, ссылка выше. Но опять же, даташит верен, если верно указан контроллер монитора по Вашим ссылкам, бывает заказываешь одно, а там что-то поменяли на аналог... Попробуйте разобраться в даташите, проинициализируйте spi самостоятельно, и инициадизируйте дисплей по даташиту. Потренироваться можно на дисплее, который Вам уже получилось включить, просто, чтобы понять, что все делаете правильно.
Подключал всеми способами (последовательным, параллельным) загружал все доступные мне библиотеки, и ни чего у меня не получилось. Лежит мой дисплей, без признаков жизни, хоть бы какую нибудь ерунду показал. А так, кроме подсветки ни чего не выдал. Буду мучать гугл, может там что накопаю.
Интересно, что вот тут http://www.e-tools.info/index.php?page=component_detail&id=3329 я нашел совершенно другую раскладку. Искал уже не от Ваших ссылок, а от фотгорафий дисплея.
Тогда получается вот так: 1-cs, 2-reset, 3-d/c, 12-scl, 13-mosi, 14-vcc, 15-gnd.
а на такой дисплей 2,4" TFT LCD Touch shield
возможно установить осциллограф?
я пытался воткнуть в скетч осциллографа библиотеки этого дисплея, что то у меня ни чего не вышло
А Вы примеры с ним просто отдельно пробовали?
Просто так работать не будет, надо переделывать всю работу с дисплеем из осцилографа.
Например, я убрал инициализацию u8g полностью и поставил вместо него свой класс с другим именем переменной, типа tft, потом заменил все вхождения методов из u8g на аналогичные методы из своего tft. При полной замене завелось сразу, только шрифты разъехались. Затем перерасчитал где и что выводить, чтобы выводилось более красиво. Затем стал оптимизировать вывод на дисплей, чтобы искличить моргание при перерисовке, чтобы все красиво и быстро работало.
Я не правильно вопрос задал, но ответ получил именно тот, который и хотел услышать)))
пример с ним есть у меня рабочий рисовалка
там к этому дисплею несколько библиотек есть но некоторые не могу запустить, какую то ошибку выдают при компиляции я погуглил, так и не понял, что он от меня хочет. А рисовалка запустилась нормально. Сын часа на два завис в рисовании на экране)))
я наивно думал, что можно скопировать ту часть скетча, где идет инициализация дисплея в скетч осциллографа и все заработает.
А можешь выложить свой скетч, со своим цветным дисплеем? Я попробую разобраться, что нужно изменить под библиотеку своего LCD
Ну, например было u8g.drawStr(12, 17+vTextShift, buffer);
а надо tft.text(12, 17+vTextShift, buffer); - Это гипотетический пример. может быть разбито на 2 разных команды, типо установки координат, а отдельно вывод текста. См. Класс для Вашего дисплея.
UPD. Неудержался и заказал себе такой же дисплейчик. Недели через 2 перепишу код под него :)
Я сам не удержался от покупки этого дисплейчика. Пока экспериментировал с подключением жки128x64 к ардуине случайно раздавил свой экран от нокии 5110. полез искать новый и купил 2,4" TFT LCD Touch shield и еще arduino uno к нему
Я сейчас хочу повторить данный осцилограф на stm32, по шустре будет в 4 раза. Думал убрать управление по uart'у и заменить на меню на дисплее и несколько кнопок. Тачскрин же прилично расширяет возможности, уже никакие кнопки делать не надо. Жаль только, что ждать придется, но цена вкусная :)
Меня смущает для ардуино, что дисплей сожрал почти все ноги.
dtvims, получилось что то на stm32 ?
Первоисточник второго показометра: http://www.semifluid.com/2013/05/28/arduino-fio-lcd-oscilloscope/
Получилось первое приближение с мониторчиком 5110, в режиме "все на авто, от 0 до 3.3В". От ADC у STM32 я ожидал большего. http://rukodelie-ds.ru/forum/viewtopic.php?f=13&t=734#p972 - тут пока кривое, но работающее решение.
Сейчас, приостановил эксперименты, т.к. занят и жду сенсорный дисплейчик (см.выше), что должен вот-вот приехать.
dtvims, Цветной экран справа это 128x160 на ST7735S?
Я думаю заказать экран побольше, без тача: 240x320 на ILI9341 за $5.57 http://www.elecfreaks.com/wiki/index.php?title=2.2S%22_TFT_LCD:_TFT01-2.2S и преобразователь уровней 3.3V <-> 5V. Тема на форуме
На сколько сложно будет переписать stm32-скетч под такой экран?
Да, справа все тот же экран, что я показывал тут на форуме, я его с ардуиной брал за эталон. Собственно источником сигнала служит шим с той же дуинки, через резистор, с парой кондесаторов на землю (можно их увидеть между дисплеями). Смотрел чтобы вид сигнала и расчет частоты были похожи. Конечно о какой-то точности говорить не приходится, калибровать просто не на чем :(
С точки зрения конкретного кода, что я сделал для stm32, то под другой дисплей надо переделать только 3 функции: вывод пикселя, вывод текста и очистку экрана. Но это решит только проблему взаимодействия с экраном. Больше по размеру и добавление цветов у др. дисплея, означает, что надо гнать больше данных по spi, что может сильно отразиться на скорости отображения и может появится сильно заметное мерцание, вот тут понадобится доп. оптимизация с отрисовкой. Я такую оптимизацию провел для дуинки: изменил функцию отрисовки линий с учетом конкретной задачи, стал обновлять только изменения (текст, только тот что изменился, лини стирать старые и сразу рисовать новые). Вариант настроек по usart'у меня как-то не очень устраивает, потому дальше надеюсь сделать на сенсорном экране меню с настройками. Еже хочу включить второй adc, создать виртуальный usb-comport и гнать по нему данные вреальном времени, чтобы обрабатывать цифровые сигналы - эх, мечты...
P.s. а зачем Вам преобразователь уровней? Запускайте все на 3.3В! Stm32 так вообще на этом напряжении работает, дисплей тоже...
а зачем Вам преобразователь уровней? Запускайте все на 3.3В! Stm32 так вообще на этом напряжении работает
Я думал его сначала на ардуине запустить. Знаю, что будет медленно - у меня уже есть 128x160 на ST7735S и он мерцает, при большем разрешении частота обновления упадет еще сильнее.
Stm32 у меня пока нету, выбираю какую плату заказать.
На ардуине должен быть переключатель или джампер, переводящий весь контроллер на питание от 3.3В.
Upd. Посмотрел на официальные платки и понял, что по ходу обладателями заветными переключателями или джамперами являются те кто купил или стронние аналоги или дешевые подделки - что-то тут не так :)
Был у меня дисплейчик побольше и за ту же цену, что 5110, см. http://we.easyelectronics.ru/lcd_gfx/podklyuchenie-tft-displeya-k-avr.html
Если кому понадобится, выложу код для данного дисплея.
Интересно было бы посмотреть на код, у меня такой же экран.
На ардуине должен быть переключатель или джампер, переводящий весь контроллер на питание от 3.3В.
3.3В найти не проблема. У меня есть и платка стабилизатора и мой "программатор" CP2102 имеет отдельные выводы с 3.3 и 5В
Для ST7735 я использовал библиотеку Adafruit и для нее доп. библиотеку Adafruit_ST7735. В последней кое что поменял/добавил "Adafruit_ST7735.cpp":
01
void
Adafruit_ST7735::drawFastLine(int8_t x, int8_t y, int8_t h,int8_t l, uint16_t color){
02
int8_t i,j,ih;
03
if
(abs(h)<5){
04
drawLine(x, y, x+l-1,y+h, color);
05
return
;
06
}
07
if
((x >= _width) || (y >= _height))
return
;
08
if
((y+h-1) >= _height) h = _height-y;
09
if
((y+h) < 0) h = -y;
10
if
((x+l-1) >= _width) l = _width-x;
11
j=h/l;
12
for
(i=0;i<l;i++){
13
if
(h>0){
14
if
(i==l-1){
15
setAddrWindow(x+i, y+i*j, x+i, y+h-1);
16
ih=h-i*j;
17
}
else
{
18
setAddrWindow(x+i, y+i*j, x+i, y+(i+1)*j-1);
19
ih=j;
20
}
21
}
else
{
22
if
(i==l-1){
23
setAddrWindow(x+i, y+h, x+i, y+i*j-1);
24
ih=-(h-i*j);
25
}
else
{
26
setAddrWindow(x+i, y+(i+1)*j, x+i, y+i*j-1);
27
ih=-j;
28
}
29
}
30
uint8_t hi = color >> 8, lo = color;
31
*rsport |= rspinmask;
32
*csport &= ~cspinmask;
33
while
(ih--) {
34
SPDR = hi;
35
while
(!(SPSR & _BV(SPIF)));
36
SPDR = lo;
37
while
(!(SPSR & _BV(SPIF)));
38
}
39
*csport |= cspinmask;
40
}
41
}
Соответсвенно в "Adafruit_ST7735.h" добавлено описание созданной функции "drawFastLine(int8_t x, int8_t y, int8_t h,int8_t l, uint16_t color),". Писал на скорую руку, только для работы с аппаратным SPI и только для быстрой отрисовки вертикальных линий отрисованных слева на право, во всех других случаях скорее всего будет рисоваться не корректно, но для конкретной задачи дает значительное ускорение.
Ну и сам код как-то так:
001
//#include "U8glib.h"
002
#include <Adafruit_GFX.h> // Core graphics library
003
#include <Adafruit_ST7735.h> // Hardware-specific library
004
#include <SPI.h>
005
#include <EEPROM.h>
006
007
// Variables you might want to play with
008
byte
useThreshold = 1;
// 0 = Off, 1 = Rising, 2 = Falling
009
byte
theThreshold = 128;
// 0-255, Multiplied by voltageConst
010
unsigned
int
timePeriod = 200;
// 0-65535, us or ms per measurement (max 0.065s or 65.535s)
011
byte
voltageRange = 1;
// 1 = 0-3.3V, 2 = 0-1.65V, 3 = 0-0.825V
012
byte
ledBacklight = 100;
013
014
boolean autoHScale =
true
;
// Automatic horizontal (time) scaling
015
boolean linesNotDots =
true
;
// Draw lines between data points
016
017
// Variables that can probably be left alone
018
const
byte
vTextShift = 65;
// Vertical text shift (to vertically align info)
019
const
byte
numOfSamples = 128;
// Leave at 100 for 128x64 pixel display
020
unsigned
int
HQadcReadings[numOfSamples];
021
byte
adcReadings[numOfSamples];
022
byte
adcOldReadings[numOfSamples];
023
byte
thresLocation = 0;
// Threshold bar location
024
float
voltageConst = 0.052381;
// Scaling factor for converting 0-63 to V
025
float
avgV = 0.0;
026
float
maxV = 0.0;
027
float
minV = 0.0;
028
float
ptopV = 0.0;
029
float
theFreq = 0;
030
031
byte
OlduseThreshold = 1;
032
byte
OldtheThreshold = 128;
033
unsigned
int
OldtimePeriod = 200;
034
float
OldavgV = 0.0;
035
float
OldmaxV = 0.0;
036
float
OldminV = 0.0;
037
float
OldptopV = 0.0;
038
float
OldtheFreq = 0;
039
040
const
byte
theAnalogPin = 7;
// Data read pin
041
042
#define sclk 13
043
#define mosi 11
044
#define cs 10
045
#define dc 8
046
#define rst 7
047
048
// SW SPI:
049
//U8GLIB_MINI12864 u8g(lcdSCK, lcdMOSI, lcdCS, lcdA0, lcdRESET);
050
// HW SPI:
051
//U8GLIB_PCD8544 u8g(lcdSCK, lcdMOSI, lcdCS, lcdA0, lcdRESET);
052
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
053
054
// High speed ADC code
055
// From: <a href="<a href="http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b0f36&topic=6549.15" rel="nofollow">http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b0f36&topic=6549.15</a>" title="<a href="http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b0f36&topic=6549.15" rel="nofollow">http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b0f36&topic=6549.15</a>" rel="nofollow"><a href="http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b..." rel="nofollow">http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b...</a></a>
056
#define FASTADC 1
057
// defines for setting and clearing register bits
058
#ifndef cbi
059
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
060
#endif
061
#ifndef sbi
062
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
063
#endif
064
065
void
collectData(
void
) {
066
unsigned
int
tempThres = 0;
067
unsigned
int
i = 0;
068
069
if
(autoHScale ==
true
) {
070
// With automatic horizontal (time) scaling enabled,
071
// scale quickly if the threshold location is far, then slow down
072
if
(thresLocation > 5*numOfSamples/8) {
073
timePeriod = timePeriod + 10;
074
}
else
if
(thresLocation < 3*numOfSamples/8) {
075
timePeriod = timePeriod - 10;
076
}
else
if
(thresLocation > numOfSamples/2) {
077
timePeriod = timePeriod + 2;
078
}
else
if
(thresLocation < numOfSamples/2) {
079
timePeriod = timePeriod - 2;
080
}
081
}
082
// Enforce minimum time periods
083
if
(timePeriod < 35) {
084
timePeriod = 35;
085
}
086
087
// Adjust voltage contstant to fit the voltage range
088
if
(voltageRange == 1) {
089
voltageConst = 0.0523810;
// 0-3.30V
090
}
else
if
(voltageRange == 2) {
091
voltageConst = 0.0261905;
// 0-1.65V
092
}
else
if
(voltageRange == 3) {
093
voltageConst = 0.0130952;
//0-0.825V
094
}
095
096
// If using threshold, wait until it has been reached
097
if
(voltageRange == 1) tempThres = theThreshold << 2;
098
else
if
(voltageRange == 2) tempThres = theThreshold << 1;
099
else
if
(voltageRange == 3) tempThres = theThreshold;
100
if
(useThreshold == 1) {
101
i = 0;
while
((analogRead(theAnalogPin)>tempThres) && (i<32768)) i++;
102
i = 0;
while
((analogRead(theAnalogPin)<tempThres) && (i<32768)) i++;
103
}
104
else
if
(useThreshold == 2) {
105
i = 0;
while
((analogRead(theAnalogPin)<tempThres) && (i<32768)) i++;
106
i = 0;
while
((analogRead(theAnalogPin)>tempThres) && (i<32768)) i++;
107
}
108
109
// Collect ADC readings
110
for
(i=0; i<numOfSamples; i++) {
111
// Takes 35 us with high speed ADC setting
112
HQadcReadings[i] = analogRead(theAnalogPin);
113
if
(timePeriod > 35)
114
delayMicroseconds(timePeriod-35);
115
}
116
for
(i=0; i<numOfSamples; i++) {
117
// Scale the readings to 0-63 and clip to 63 if they are out of range.
118
if
(voltageRange == 1) {
119
if
(HQadcReadings[i]>>4 < 0b111111) adcReadings[i] = HQadcReadings[i]>>4 & 0b111111;
120
else
adcReadings[i] = 0b111111;
121
}
else
if
(voltageRange == 2) {
122
if
(HQadcReadings[i]>>3 < 0b111111) adcReadings[i] = HQadcReadings[i]>>3 & 0b111111;
123
else
adcReadings[i] = 0b111111;
124
}
else
if
(voltageRange == 3) {
125
if
(HQadcReadings[i]>>2 < 0b111111) adcReadings[i] = HQadcReadings[i]>>2 & 0b111111;
126
else
adcReadings[i] = 0b111111;
127
}
128
// Invert for display
129
adcReadings[i] = 63-adcReadings[i];
130
}
131
132
// Calculate and display frequency of signal using zero crossing
133
if
(useThreshold != 0) {
134
if
(useThreshold == 1) {
135
thresLocation = 1;
136
while
((adcReadings[thresLocation]<(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
137
thresLocation++;
138
while
((adcReadings[thresLocation]>(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
139
}
140
else
if
(useThreshold == 2) {
141
thresLocation = 1;
142
while
((adcReadings[thresLocation]>(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
143
thresLocation++;
144
while
((adcReadings[thresLocation]<(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
145
}
146
147
theFreq = (
float
) 1000/(thresLocation * timePeriod) * 1000;
148
}
149
150
// Average Voltage
151
avgV = 0;
152
for
(i=0; i<numOfSamples; i++)
153
avgV = avgV + adcReadings[i];
154
avgV = (63-(avgV / numOfSamples)) * voltageConst;
155
156
// Maximum Voltage
157
maxV = 63;
158
for
(i=0; i<numOfSamples; i++)
159
if
(adcReadings[i]<maxV) maxV = adcReadings[i];
160
maxV = (63-maxV) * voltageConst;
161
162
// Minimum Voltage
163
minV = 0;
164
for
(i=0; i<numOfSamples; i++)
165
if
(adcReadings[i]>minV) minV = adcReadings[i];
166
minV = (63-minV) * voltageConst;
167
168
// Peak-to-Peak Voltage
169
ptopV = maxV - minV;
170
}
171
172
void
handleSerial(
void
) {
173
char
inByte;
174
char
dataByte;
175
boolean exitLoop =
false
;
176
do
{
177
// Clear out buffer
178
do
{
179
inByte =
Serial
.read();
180
}
while
(
Serial
.available() > 0);
181
182
Serial
.print(
"\nArduino LCD Oscilloscope\n"
);
183
Serial
.print(
" 1 - Change threshold usage (currently: "
);
184
if
(useThreshold == 0)
Serial
.print(
"Off)\n"
);
185
else
if
(useThreshold == 1)
Serial
.print(
"Rise)\n"
);
186
else
if
(useThreshold == 2)
Serial
.print(
"Fall)\n"
);
187
Serial
.print(
" 2 - Change threshold value (currently: "
);
188
Serial
.print(theThreshold, DEC);
Serial
.print(
")\n"
);
189
Serial
.print(
" 3 - Change sampling period (currently: "
);
190
Serial
.print(timePeriod, DEC);
Serial
.print(
")\n"
);
191
Serial
.print(
" 4 - Change voltage range (currently: "
);
192
if
(voltageRange == 1)
Serial
.print(
"0-3.3V)\n"
);
193
else
if
(voltageRange == 2)
Serial
.print(
"0-1.65V)\n"
);
194
else
if
(voltageRange == 3)
Serial
.print(
"0-0.825V)\n"
);
195
Serial
.print(
" 5 - Toggle auto horizontal (time) scaling (currently: "
);
196
if
(autoHScale ==
true
)
Serial
.print(
"On)\n"
);
197
else
if
(autoHScale ==
false
)
Serial
.print(
"Off)\n"
);
198
Serial
.print(
" 8 - Exit\n"
);
199
200
// Wait for input/response, refresh display while in menu
201
do
{
202
collectData();
203
draw1();
204
// Picture Display Loop
205
//!!! u8g.firstPage();
206
// do { draw(); } while(
207
//!!! u8g.nextPage()
208
// );
209
}
while
(
Serial
.available() == 0);
210
inByte =
Serial
.read();
211
212
if
(inByte ==
'1'
) {
213
Serial
.print(
"Change threshold usage\n"
);
214
Serial
.print(
" 0 - Off\n"
);
215
Serial
.print(
" 1 - Rise\n"
);
216
Serial
.print(
" 2 - Fall\n"
);
217
do
{ }
while
(
Serial
.available() == 0);
218
dataByte =
Serial
.read();
219
if
(dataByte ==
'0'
) useThreshold = 0;
220
else
if
(dataByte ==
'1'
) useThreshold = 1;
221
else
if
(dataByte ==
'2'
) useThreshold = 2;
222
}
else
if
(inByte ==
'2'
) {
223
Serial
.print(
"Change threshold value (thresholds for 0-3.3V,0-1.65V,0-0.825V ranges)\n"
);
224
Serial
.print(
" 0 - 32 (0.41V, 0.21V, 0.10V)\n"
);
225
Serial
.print(
" 1 - 80 (1.04V, 0.52V, 0.26V)\n"
);
226
Serial
.print(
" 2 - 128 (1.66V, 0.83V, 0.41V)\n"
);
227
Serial
.print(
" 3 - 176 (2.28V, 1.14V, 0.57V)\n"
);
228
Serial
.print(
" 4 - 224 (2.90V, 1.45V, 0.72V)\n"
);
229
do
{ }
while
(
Serial
.available() == 0);
230
dataByte =
Serial
.read();
231
if
(dataByte ==
'0'
) theThreshold = 32;
232
else
if
(dataByte ==
'1'
) theThreshold = 80;
233
else
if
(dataByte ==
'2'
) theThreshold = 128;
234
else
if
(dataByte ==
'3'
) theThreshold = 176;
235
else
if
(dataByte ==
'4'
) theThreshold = 224;
236
}
else
if
(inByte ==
'3'
) {
237
Serial
.print(
"Change sampling frequency\n"
);
238
Serial
.print(
" 0 - 28 kHz (35 us/sample)\n"
);
239
Serial
.print(
" 1 - 20 kHz (50 us/sample)\n"
);
240
Serial
.print(
" 2 - 10 kHz (100 us/sample)\n"
);
241
Serial
.print(
" 3 - 5 kHz (200 us/sample)\n"
);
242
Serial
.print(
" 4 - 2.5 kHz (400 us/sample)\n"
);
243
do
{ }
while
(
Serial
.available() == 0);
244
dataByte =
Serial
.read();
245
if
(dataByte ==
'0'
) timePeriod = 35;
246
else
if
(dataByte ==
'1'
) timePeriod = 50;
247
else
if
(dataByte ==
'2'
) timePeriod = 100;
248
else
if
(dataByte ==
'3'
) timePeriod = 200;
249
else
if
(dataByte ==
'4'
) timePeriod = 400;
250
}
else
if
(inByte ==
'4'
) {
251
Serial
.print(
"Change voltage range\n"
);
252
Serial
.print(
" 1 - 0-3.3V\n"
);
253
Serial
.print(
" 2 - 0-1.65V\n"
);
254
Serial
.print(
" 3 - 0-0.825V\n"
);
255
do
{ }
while
(
Serial
.available() == 0);
256
dataByte =
Serial
.read();
257
if
(dataByte ==
'1'
) voltageRange = 1;
258
else
if
(dataByte ==
'2'
) voltageRange = 2;
259
else
if
(dataByte ==
'3'
) voltageRange = 3;
260
}
else
if
(inByte ==
'5'
) {
261
Serial
.print(
"Toggle auto horizontal (time) scaling\n"
);
262
Serial
.print(
" 0 - Off\n"
);
263
Serial
.print(
" 1 - On\n"
);
264
do
{ }
while
(
Serial
.available() == 0);
265
dataByte =
Serial
.read();
266
if
(dataByte ==
'0'
) autoHScale =
false
;
267
else
if
(dataByte ==
'1'
) autoHScale =
true
;
268
}
else
if
(inByte ==
'8'
) {
269
Serial
.print(
"Bye!\n"
);
270
exitLoop =
true
;
271
}
272
draw();
273
}
while
(exitLoop ==
false
);
274
}
275
276
void
drawD(
void
) {
277
char
buffer[16];
278
if
(avgV!=OldavgV){
279
tft.setTextColor(ST7735_BLACK);
280
dtostrf(OldavgV, 3, 2, buffer);
281
tft.setCursor(15, 5+vTextShift);
282
tft.print(buffer);
283
tft.setTextColor(ST7735_RED);
284
dtostrf(avgV, 3, 2, buffer);
285
tft.setCursor(15, 5+vTextShift);
286
tft.print(buffer);
287
OldavgV=avgV;
288
}
289
if
(maxV!=OldmaxV){
290
tft.setTextColor(ST7735_BLACK);
291
dtostrf(OldmaxV, 3, 2, buffer);
292
tft.setCursor(15, 2+11+vTextShift);
293
tft.print(buffer);
294
tft.setTextColor(ST7735_RED);
295
dtostrf(maxV, 3, 2, buffer);
296
tft.setCursor(15, 2+11+vTextShift);
297
tft.print(buffer);
298
OldmaxV=maxV;
299
}
300
if
(minV!=OldminV){
301
tft.setTextColor(ST7735_BLACK);
302
dtostrf(OldminV, 3, 2, buffer);
303
tft.setCursor(15, 4+17+vTextShift);
304
tft.print(buffer);
305
tft.setTextColor(ST7735_RED);
306
dtostrf(minV, 3, 2, buffer);
307
tft.setCursor(15, 4+17+vTextShift);
308
tft.print(buffer);
309
OldminV=minV;
310
}
311
if
(ptopV!=OldptopV){
312
tft.setTextColor(ST7735_BLACK);
313
dtostrf(OldptopV, 3, 2, buffer);
314
tft.setCursor(15, 6+23+vTextShift);
315
tft.print(buffer);
316
tft.setTextColor(ST7735_RED);
317
dtostrf(ptopV, 3, 2, buffer);
318
tft.setCursor(15, 6+23+vTextShift);
319
tft.print(buffer);
320
OldptopV=ptopV;
321
}
322
if
(theFreq!=OldtheFreq){
323
tft.setTextColor(ST7735_BLACK);
324
dtostrf(OldtheFreq, 5, 0, buffer);
325
tft.setCursor(0, 16+53+vTextShift);
326
tft.print(buffer);
327
tft.setTextColor(ST7735_RED);
328
dtostrf(theFreq, 5, 0, buffer);
329
tft.setCursor(0, 16+53+vTextShift);
330
tft.print(buffer);
331
OldtheFreq=theFreq;
332
}
333
/*if (useThreshold == 0) {
334
tft.setCursor(15, 8+29+vTextShift);
335
tft.print("Off");
336
} else if (useThreshold == 1) {
337
tft.setCursor(15, 8+29+vTextShift);
338
tft.print("Rise");
339
dtostrf((float) (theThreshold>>2) * voltageConst, 3, 2, buffer);
340
} else if (useThreshold == 2) {
341
tft.setCursor(15, 8+29+vTextShift);
342
tft.print("Fall");
343
dtostrf((float) (theThreshold>>2) * voltageConst, 3, 2, buffer);
344
}
345
tft.setCursor(11, 10+35+vTextShift);
346
tft.print(buffer);*/
347
// Correctly format the text so that there are always 4 characters
348
if
(timePeriod!=OldtimePeriod){
349
tft.setTextColor(ST7735_BLACK);
350
if
(OldtimePeriod < 400) {
351
dtostrf((
float
) OldtimePeriod/1000 * 25, 3, 2, buffer);
352
}
else
if
(OldtimePeriod < 4000) {
353
dtostrf((
float
) OldtimePeriod/1000 * 25, 3, 1, buffer);
354
}
else
if
(OldtimePeriod < 40000) {
355
dtostrf((
float
) OldtimePeriod/1000 * 25, 3, 0, buffer);
356
}
else
{
// Out of range
357
dtostrf((
float
) 0.00, 3, 2, buffer);
358
}
359
tft.setCursor(15, 12+41+vTextShift);
360
tft.print(buffer);
361
362
tft.setTextColor(ST7735_RED);
363
if
(timePeriod < 400) {
364
dtostrf((
float
) timePeriod/1000 * 25, 3, 2, buffer);
365
}
else
if
(timePeriod < 4000) {
366
dtostrf((
float
) timePeriod/1000 * 25, 3, 1, buffer);
367
}
else
if
(timePeriod < 40000) {
368
dtostrf((
float
) timePeriod/1000 * 25, 3, 0, buffer);
369
}
else
{
// Out of range
370
dtostrf((
float
) 0.00, 3, 2, buffer);
371
}
372
tft.setCursor(15, 12+41+vTextShift);
373
tft.print(buffer);
374
OldtimePeriod=timePeriod;
375
}
376
/*if (voltageRange == 1) {
377
tft.setCursor(7, 18+59+vTextShift);
378
tft.print("0-3.30");
379
} else if (voltageRange == 2) {
380
tft.setCursor(7, 18+59+vTextShift);
381
tft.print("0-1.65");
382
} else if (voltageRange == 3) {
383
tft.setCursor(7, 18+59+vTextShift);
384
tft.print("0-0.83");
385
} */
386
}
387
void
drawT(
void
) {
388
char
buffer[16];
389
tft.fillRect(0,vTextShift+5,45,150,ST7735_BLACK);
390
tft.setTextColor(ST7735_RED);
391
tft.setTextSize(1);
392
tft.setCursor(0, 5+vTextShift);
393
tft.print(
"Av"
);
394
tft.setCursor(0, 2+11+vTextShift);
395
tft.print(
"Mx"
);
396
tft.setCursor(0, 4+17+vTextShift);
397
tft.print(
"Mn"
);
398
tft.setCursor(0, 6+23+vTextShift);
399
tft.print(
"PP"
);
400
tft.setCursor(0, 8+29+vTextShift);
401
tft.print(
"Th"
);
402
tft.setCursor(0, 10+35+vTextShift);
403
tft.print(
"V"
);
404
tft.setCursor(0, 12+41+vTextShift);
405
tft.print(
"Tm"
);
406
tft.setCursor(4, 14+47+vTextShift);
407
tft.print(
"ms/div"
);
408
tft.setCursor(31, 16+53+vTextShift);
409
tft.print(
"Hz"
);
410
tft.setCursor(0, 18+59+vTextShift);
411
tft.print(
"R"
);
412
413
// Draw dynamic text
414
if
(autoHScale ==
true
) {
415
tft.setCursor(120, 2);
416
tft.print(
"A"
);
417
}
418
dtostrf(avgV, 3, 2, buffer);
419
tft.setCursor(15, 5+vTextShift);
420
tft.print(buffer);
421
422
dtostrf(maxV, 3, 2, buffer);
423
tft.setCursor(15, 2+11+vTextShift);
424
tft.print(buffer);
425
426
dtostrf(minV, 3, 2, buffer);
427
tft.setCursor(15, 4+17+vTextShift);
428
tft.print(buffer);
429
430
dtostrf(ptopV, 3, 2, buffer);
431
tft.setCursor(15, 6+23+vTextShift);
432
tft.print(buffer);
433
434
dtostrf(theFreq, 5, 0, buffer);
435
tft.setCursor(0, 16+53+vTextShift);
436
tft.print(buffer);
437
438
if
(useThreshold == 0) {
439
tft.setCursor(15, 8+29+vTextShift);
440
tft.print(
"Off"
);
441
}
else
if
(useThreshold == 1) {
442
tft.setCursor(15, 8+29+vTextShift);
443
tft.print(
"Rise"
);
444
dtostrf((
float
) (theThreshold>>2) * voltageConst, 3, 2, buffer);
445
}
else
if
(useThreshold == 2) {
446
tft.setCursor(15, 8+29+vTextShift);
447
tft.print(
"Fall"
);
448
dtostrf((
float
) (theThreshold>>2) * voltageConst, 3, 2, buffer);
449
}
450
tft.setCursor(11, 10+35+vTextShift);
451
tft.print(buffer);
452
// Correctly format the text so that there are always 4 characters
453
if
(timePeriod < 400) {
454
dtostrf((
float
) timePeriod/1000 * 25, 3, 2, buffer);
455
}
else
if
(timePeriod < 4000) {
456
dtostrf((
float
) timePeriod/1000 * 25, 3, 1, buffer);
457
}
else
if
(timePeriod < 40000) {
458
dtostrf((
float
) timePeriod/1000 * 25, 3, 0, buffer);
459
}
else
{
// Out of range
460
dtostrf((
float
) 0.00, 3, 2, buffer);
461
}
462
tft.setCursor(15, 12+41+vTextShift);
463
tft.print(buffer);
464
if
(voltageRange == 1) {
465
tft.setCursor(7, 18+59+vTextShift);
466
tft.print(
"0-3.30"
);
467
}
else
if
(voltageRange == 2) {
468
tft.setCursor(7, 18+59+vTextShift);
469
tft.print(
"0-1.65"
);
470
}
else
if
(voltageRange == 3) {
471
tft.setCursor(7, 18+59+vTextShift);
472
tft.print(
"0-0.83"
);
473
}
474
OlduseThreshold = useThreshold;
475
OldtheThreshold = theThreshold;
476
OldtimePeriod = timePeriod;
477
OldavgV = avgV;
478
OldmaxV = maxV;
479
OldminV = minV;
480
OldptopV = ptopV;
481
OldtheFreq = theFreq;
482
}
483
484
void
draw(
void
) {
485
tft.fillScreen(ST7735_BLACK);
486
drawT();
487
draw1();
488
}
489
490
void
draw1(
void
) {
491
int
i;
492
if
(useThreshold != 0)
493
for
(i=0; i<127; i+=3){
494
tft.drawPixel(i,63-(theThreshold>>2),ST7735_YELLOW);
495
tft.drawPixel(i,63,ST7735_YELLOW);
496
}
497
for
(i=0; i<63; i+=5) {
498
tft.drawPixel(32,i,ST7735_YELLOW);
499
tft.drawPixel(64,i,ST7735_YELLOW);
500
tft.drawPixel(96,i,ST7735_YELLOW);
501
tft.drawPixel(127,i,ST7735_YELLOW);
502
}
503
tft.drawFastLine(1+(128-numOfSamples)-1,adcOldReadings[0],adcOldReadings[1]-adcOldReadings[0],2, ST7735_BLACK);
504
for
(i=1; i<numOfSamples-1; i++){
// Draw using lines
505
tft.drawFastLine(i+(128-numOfSamples),adcOldReadings[i],adcOldReadings[i+1]-adcOldReadings[i],2, ST7735_BLACK);
506
tft.drawFastLine(i+(128-numOfSamples)-1,adcReadings[i-1],adcReadings[i]-adcReadings[i-1],2, ST7735_WHITE);
507
adcOldReadings[i-1]=adcReadings[i-1];
508
}
509
tft.drawFastLine(127+(128-numOfSamples)-1,adcReadings[126],adcReadings[127]-adcReadings[126],2, ST7735_WHITE);
510
adcOldReadings[126]=adcReadings[126];
511
adcOldReadings[127]=adcReadings[127];
512
}
513
514
void
setup
() {
515
Serial
.begin(9600);
516
tft.initR(INITR_BLACKTAB);
517
tft.fillScreen(ST7735_BLACK);
518
// Turn on LED backlight
519
analogWrite(3, ledBacklight);
520
521
#if FASTADC
522
// set prescale to 16
523
sbi(ADCSRA,ADPS2) ;
524
cbi(ADCSRA,ADPS1) ;
525
cbi(ADCSRA,ADPS0) ;
526
#endif
527
delay(100);
528
draw();
529
}
530
531
int
j=8;
532
533
void
loop
() {
534
535
collectData();
536
draw1();
537
drawD();
538
if
(j==100){
539
drawT();
540
j=0;
541
}
542
j++;
543
544
// If user sends any serial data, show menu
545
if
(
Serial
.available() > 0) {
546
handleSerial();
547
}
548
549
// rebuild the picture after some delay
550
delay(100);
//Можно убрать
551
}
Настройка "соединять линиями или отображать точками" полностью отключена, только линиями рисуем. На 3-м пине ШИМ, который я подключал не к дисплею (вообше шимом напрямую лучше дисплей не подсвечивать, а давать питание на дисплей напрямую от источника питания), а через резистор в несколько килоОм к пину ADC, теперь Если между ADC и землей поставить конденсатор на 0.1мкф, то на графике получается красивое сглаживание :)
P.s. Забрал сегодня с почты сенсорный дисплей. Прикольная штука, жаль, что немного поцарапаный оказался :(, причем НЕ нашей почтой, ибо упакован был так, что выдержал бы взрыв :), с другой стороны всего около 8 баксов с доставкой.
UPD. В дисплейчике для согласования уровней используется логика hc245. Поискал в продаже, окалось, достаточно дешевый чип и есть в наличии. Можно использовать :)
Спасибо, попробую на своем экранчике вечером. А в закомментированных фрагментах №2 и 3, что там за логика?
Это я не стал делать отрисовку текста, что меняется только от настроек
Мини осциллограф работает отлично. Т.к. я уже наигрался с ST7735 низкая частота обновления экрана не огорчила.
Чувствую, пора заказывать экран с параллельным интерфейсом и Stm32 дискавери или другую плату АРМом и быстрым АЦП
У экрана частота обновления супер, просто spi у дуины медленный.
Определился с экраном - буду брать 2.8 Inch 240 x 320 ili9325 can connect any 16 bit data bus, подключать буду к ATmega128 через преобразователь уровней, шить через ISP ардуиной. С Stm32 дискавери решил повременить, я полный ноль в армах и Stm32.
Сложно будет переписать скетч под такой экран? (u8glib этот контроллер не поддерживает, придется перейти на UTFT)
Adafruit обычно имеет доп. библиотечки под конкретные моники, а если нет, то легко самому набрасать, библиотека очень простая. U8glib достаточно сложная в добавлении новых дисплеев, но тоже можно погуглить и возможно найти код и для нужного дисплея.
а на такой дисплей 2,4" TFT LCD Touch shield
возможно установить осциллограф?
Времени мало в последнее время, но вот набросал кое что на скорую руку:
1. Скачал пример http://misc.ws/wp-content/uploads/2013/11/TFTLCD.zip, который сразу не пошел, была ошибка компиляции, но есть решение вот тут: http://forum.arduino.cc/index.php?topic=185924.msg1380185#msg1380185
2. переделал скетч, сделал сразу несколько доп. правок: Коррекция автомасштабирования, чтобы поменьше скакал график на стабильном сигнале; убрал явный программный мусор (остатки прошлого); Переменная numOfSamples является по сути шириной сетки осциллографа.
3. Есть бага: при некотором увеличении numOfSamples (например до 255) начинается свистопляска, судя по всему просто заканчивается оперативная память и массив выборки ADC начинает наезжать на стек.
4. Если все-равно памяти мало, то можно увеличивать ширину линий и размеры шрифтов, благо места навалом.
001
#define LCD_CS A3
002
#define LCD_CD A2
003
#define LCD_WR A1
004
#define LCD_RD A0
005
#define LCD_RESET A4
006
007
#define BLACK 0x0000
008
#define BLUE 0x001F
009
#define RED 0xF800
010
#define GREEN 0x07E0
011
#define CYAN 0x07FF
012
#define MAGENTA 0xF81F
013
#define YELLOW 0xFFE0
014
#define WHITE 0xFFFF
015
016
#include "TFTLCD.h"
017
#include <EEPROM.h>
018
019
TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
020
021
022
023
// Variables you might want to play with
024
byte
useThreshold = 1;
// 0 = Off, 1 = Rising, 2 = Falling
025
byte
theThreshold = 128;
// 0-255, Multiplied by voltageConst
026
unsigned
int
timePeriod = 200;
// 0-65535, us or ms per measurement (max 0.065s or 65.535s)
027
byte
voltageRange = 1;
// 1 = 0-3.3V, 2 = 0-1.65V, 3 = 0-0.825V
028
byte
ledBacklight = 100;
029
030
boolean autoHScale =
true
;
// Automatic horizontal (time) scaling
031
boolean linesNotDots =
true
;
// Draw lines between data points
032
033
// Variables that can probably be left alone
034
const
byte
vTextShift = 65;
// Vertical text shift (to vertically align info)
035
const
byte
numOfSamples = 170;
// Leave at 100 for 128x64 pixel display
036
unsigned
int
HQadcReadings[numOfSamples];
037
byte
adcReadings[numOfSamples];
038
byte
adcOldReadings[numOfSamples];
039
byte
thresLocation = 0;
// Threshold bar location
040
float
voltageConst = 0.052381;
// Scaling factor for converting 0-63 to V
041
float
avgV = 0.0;
042
float
maxV = 0.0;
043
float
minV = 0.0;
044
float
ptopV = 0.0;
045
float
theFreq = 0;
046
047
byte
OlduseThreshold = 1;
048
byte
OldtheThreshold = 128;
049
unsigned
int
OldtimePeriod = 200;
050
float
OldavgV = 0.0;
051
float
OldmaxV = 0.0;
052
float
OldminV = 0.0;
053
float
OldptopV = 0.0;
054
float
OldtheFreq = 0;
055
056
const
byte
theAnalogPin = 7;
// Data read pin
057
058
059
// High speed ADC code
060
// From: <a href="<a href="http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b0f36&topic=6549.15" rel="nofollow">http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b0f36&topic=6549.15</a>" title="<a href="http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b0f36&topic=6549.15" rel="nofollow">http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b0f36&topic=6549.15</a>" rel="nofollow"><a href="http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b..." rel="nofollow">http://forum.arduino.cc/index.php?PHPSESSID=e21f9a71b887039092c91a516f9b...</a></a>
061
#define FASTADC 1
062
// defines for setting and clearing register bits
063
#ifndef cbi
064
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
065
#endif
066
#ifndef sbi
067
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
068
#endif
069
070
void
collectData(
void
) {
071
unsigned
int
tempThres = 0;
072
unsigned
int
i = 0;
073
074
if
(autoHScale ==
true
) {
075
// With automatic horizontal (time) scaling enabled,
076
// scale quickly if the threshold location is far, then slow down
077
if
(thresLocation > 5*numOfSamples/8) {
078
timePeriod = timePeriod + 10;
079
}
else
if
(thresLocation < 3*numOfSamples/8) {
080
timePeriod = timePeriod - 10;
081
}
else
if
(thresLocation > numOfSamples/2+1) {
082
timePeriod = timePeriod + 2;
083
}
else
if
(thresLocation < numOfSamples/2-1) {
084
timePeriod = timePeriod - 2;
085
}
086
}
087
// Enforce minimum time periods
088
if
(timePeriod < 35) {
089
timePeriod = 35;
090
}
091
092
// Adjust voltage contstant to fit the voltage range
093
if
(voltageRange == 1) {
094
voltageConst = 0.0523810;
// 0-3.30V
095
}
else
if
(voltageRange == 2) {
096
voltageConst = 0.0261905;
// 0-1.65V
097
}
else
if
(voltageRange == 3) {
098
voltageConst = 0.0130952;
//0-0.825V
099
}
100
101
// If using threshold, wait until it has been reached
102
if
(voltageRange == 1) tempThres = theThreshold << 2;
103
else
if
(voltageRange == 2) tempThres = theThreshold << 1;
104
else
if
(voltageRange == 3) tempThres = theThreshold;
105
if
(useThreshold == 1) {
106
i = 0;
while
((analogRead(theAnalogPin)>tempThres) && (i<32768)) i++;
107
i = 0;
while
((analogRead(theAnalogPin)<tempThres) && (i<32768)) i++;
108
}
109
else
if
(useThreshold == 2) {
110
i = 0;
while
((analogRead(theAnalogPin)<tempThres) && (i<32768)) i++;
111
i = 0;
while
((analogRead(theAnalogPin)>tempThres) && (i<32768)) i++;
112
}
113
114
// Collect ADC readings
115
for
(i=0; i<numOfSamples; i++) {
116
// Takes 35 us with high speed ADC setting
117
HQadcReadings[i] = analogRead(theAnalogPin);
118
if
(timePeriod > 35)
119
delayMicroseconds(timePeriod-35);
120
}
121
for
(i=0; i<numOfSamples; i++) {
122
// Scale the readings to 0-63 and clip to 63 if they are out of range.
123
if
(voltageRange == 1) {
124
if
(HQadcReadings[i]>>4 < 0b111111) adcReadings[i] = HQadcReadings[i]>>4 & 0b111111;
125
else
adcReadings[i] = 0b111111;
126
}
else
if
(voltageRange == 2) {
127
if
(HQadcReadings[i]>>3 < 0b111111) adcReadings[i] = HQadcReadings[i]>>3 & 0b111111;
128
else
adcReadings[i] = 0b111111;
129
}
else
if
(voltageRange == 3) {
130
if
(HQadcReadings[i]>>2 < 0b111111) adcReadings[i] = HQadcReadings[i]>>2 & 0b111111;
131
else
adcReadings[i] = 0b111111;
132
}
133
// Invert for display
134
adcReadings[i] = 63-adcReadings[i];
135
}
136
137
// Calculate and display frequency of signal using zero crossing
138
if
(useThreshold != 0) {
139
if
(useThreshold == 1) {
140
thresLocation = 1;
141
while
((adcReadings[thresLocation]<(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
142
thresLocation++;
143
while
((adcReadings[thresLocation]>(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
144
}
145
else
if
(useThreshold == 2) {
146
thresLocation = 1;
147
while
((adcReadings[thresLocation]>(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
148
thresLocation++;
149
while
((adcReadings[thresLocation]<(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
150
}
151
152
theFreq = (
float
) 1000/(thresLocation * timePeriod) * 1000;
153
}
154
155
// Average Voltage
156
avgV = 0;
157
for
(i=0; i<numOfSamples; i++)
158
avgV = avgV + adcReadings[i];
159
avgV = (63-(avgV / numOfSamples)) * voltageConst;
160
161
// Maximum Voltage
162
maxV = 63;
163
for
(i=0; i<numOfSamples; i++)
164
if
(adcReadings[i]<maxV) maxV = adcReadings[i];
165
maxV = (63-maxV) * voltageConst;
166
167
// Minimum Voltage
168
minV = 0;
169
for
(i=0; i<numOfSamples; i++)
170
if
(adcReadings[i]>minV) minV = adcReadings[i];
171
minV = (63-minV) * voltageConst;
172
173
// Peak-to-Peak Voltage
174
ptopV = maxV - minV;
175
}
176
177
void
handleSerial(
void
) {
178
char
inByte;
179
char
dataByte;
180
boolean exitLoop =
false
;
181
do
{
182
// Clear out buffer
183
do
{
184
inByte =
Serial
.read();
185
}
while
(
Serial
.available() > 0);
186
187
Serial
.print(
"\nArduino LCD Oscilloscope\n"
);
188
Serial
.print(
" 1 - Change threshold usage (currently: "
);
189
if
(useThreshold == 0)
Serial
.print(
"Off)\n"
);
190
else
if
(useThreshold == 1)
Serial
.print(
"Rise)\n"
);
191
else
if
(useThreshold == 2)
Serial
.print(
"Fall)\n"
);
192
Serial
.print(
" 2 - Change threshold value (currently: "
);
193
Serial
.print(theThreshold, DEC);
Serial
.print(
")\n"
);
194
Serial
.print(
" 3 - Change sampling period (currently: "
);
195
Serial
.print(timePeriod, DEC);
Serial
.print(
")\n"
);
196
Serial
.print(
" 4 - Change voltage range (currently: "
);
197
if
(voltageRange == 1)
Serial
.print(
"0-3.3V)\n"
);
198
else
if
(voltageRange == 2)
Serial
.print(
"0-1.65V)\n"
);
199
else
if
(voltageRange == 3)
Serial
.print(
"0-0.825V)\n"
);
200
Serial
.print(
" 5 - Toggle auto horizontal (time) scaling (currently: "
);
201
if
(autoHScale ==
true
)
Serial
.print(
"On)\n"
);
202
else
if
(autoHScale ==
false
)
Serial
.print(
"Off)\n"
);
203
Serial
.print(
" 8 - Exit\n"
);
204
205
// Wait for input/response, refresh display while in menu
206
do
{
207
collectData();
208
draw1();
209
}
while
(
Serial
.available() == 0);
210
inByte =
Serial
.read();
211
212
if
(inByte ==
'1'
) {
213
Serial
.print(
"Change threshold usage\n"
);
214
Serial
.print(
" 0 - Off\n"
);
215
Serial
.print(
" 1 - Rise\n"
);
216
Serial
.print(
" 2 - Fall\n"
);
217
do
{ }
while
(
Serial
.available() == 0);
218
dataByte =
Serial
.read();
219
if
(dataByte ==
'0'
) useThreshold = 0;
220
else
if
(dataByte ==
'1'
) useThreshold = 1;
221
else
if
(dataByte ==
'2'
) useThreshold = 2;
222
}
else
if
(inByte ==
'2'
) {
223
Serial
.print(
"Change threshold value (thresholds for 0-3.3V,0-1.65V,0-0.825V ranges)\n"
);
224
Serial
.print(
" 0 - 32 (0.41V, 0.21V, 0.10V)\n"
);
225
Serial
.print(
" 1 - 80 (1.04V, 0.52V, 0.26V)\n"
);
226
Serial
.print(
" 2 - 128 (1.66V, 0.83V, 0.41V)\n"
);
227
Serial
.print(
" 3 - 176 (2.28V, 1.14V, 0.57V)\n"
);
228
Serial
.print(
" 4 - 224 (2.90V, 1.45V, 0.72V)\n"
);
229
do
{ }
while
(
Serial
.available() == 0);
230
dataByte =
Serial
.read();
231
if
(dataByte ==
'0'
) theThreshold = 32;
232
else
if
(dataByte ==
'1'
) theThreshold = 80;
233
else
if
(dataByte ==
'2'
) theThreshold = 128;
234
else
if
(dataByte ==
'3'
) theThreshold = 176;
235
else
if
(dataByte ==
'4'
) theThreshold = 224;
236
}
else
if
(inByte ==
'3'
) {
237
Serial
.print(
"Change sampling frequency\n"
);
238
Serial
.print(
" 0 - 28 kHz (35 us/sample)\n"
);
239
Serial
.print(
" 1 - 20 kHz (50 us/sample)\n"
);
240
Serial
.print(
" 2 - 10 kHz (100 us/sample)\n"
);
241
Serial
.print(
" 3 - 5 kHz (200 us/sample)\n"
);
242
Serial
.print(
" 4 - 2.5 kHz (400 us/sample)\n"
);
243
do
{ }
while
(
Serial
.available() == 0);
244
dataByte =
Serial
.read();
245
if
(dataByte ==
'0'
) timePeriod = 35;
246
else
if
(dataByte ==
'1'
) timePeriod = 50;
247
else
if
(dataByte ==
'2'
) timePeriod = 100;
248
else
if
(dataByte ==
'3'
) timePeriod = 200;
249
else
if
(dataByte ==
'4'
) timePeriod = 400;
250
}
else
if
(inByte ==
'4'
) {
251
Serial
.print(
"Change voltage range\n"
);
252
Serial
.print(
" 1 - 0-3.3V\n"
);
253
Serial
.print(
" 2 - 0-1.65V\n"
);
254
Serial
.print(
" 3 - 0-0.825V\n"
);
255
do
{ }
while
(
Serial
.available() == 0);
256
dataByte =
Serial
.read();
257
if
(dataByte ==
'1'
) voltageRange = 1;
258
else
if
(dataByte ==
'2'
) voltageRange = 2;
259
else
if
(dataByte ==
'3'
) voltageRange = 3;
260
}
else
if
(inByte ==
'5'
) {
261
Serial
.print(
"Toggle auto horizontal (time) scaling\n"
);
262
Serial
.print(
" 0 - Off\n"
);
263
Serial
.print(
" 1 - On\n"
);
264
do
{ }
while
(
Serial
.available() == 0);
265
dataByte =
Serial
.read();
266
if
(dataByte ==
'0'
) autoHScale =
false
;
267
else
if
(dataByte ==
'1'
) autoHScale =
true
;
268
}
else
if
(inByte ==
'8'
) {
269
Serial
.print(
"Bye!\n"
);
270
exitLoop =
true
;
271
}
272
draw();
273
}
while
(exitLoop ==
false
);
274
}
275
276
void
drawD(
void
) {
277
char
buffer[16];
278
if
(avgV!=OldavgV){
279
tft.setTextColor(BLACK);
280
dtostrf(OldavgV, 3, 2, buffer);
281
tft.setCursor(15, 5+vTextShift);
282
tft.print(buffer);
283
tft.setTextColor(RED);
284
dtostrf(avgV, 3, 2, buffer);
285
tft.setCursor(15, 5+vTextShift);
286
tft.print(buffer);
287
OldavgV=avgV;
288
}
289
if
(maxV!=OldmaxV){
290
tft.setTextColor(BLACK);
291
dtostrf(OldmaxV, 3, 2, buffer);
292
tft.setCursor(15, 2+11+vTextShift);
293
tft.print(buffer);
294
tft.setTextColor(RED);
295
dtostrf(maxV, 3, 2, buffer);
296
tft.setCursor(15, 2+11+vTextShift);
297
tft.print(buffer);
298
OldmaxV=maxV;
299
}
300
if
(minV!=OldminV){
301
tft.setTextColor(BLACK);
302
dtostrf(OldminV, 3, 2, buffer);
303
tft.setCursor(15, 4+17+vTextShift);
304
tft.print(buffer);
305
tft.setTextColor(RED);
306
dtostrf(minV, 3, 2, buffer);
307
tft.setCursor(15, 4+17+vTextShift);
308
tft.print(buffer);
309
OldminV=minV;
310
}
311
if
(ptopV!=OldptopV){
312
tft.setTextColor(BLACK);
313
dtostrf(OldptopV, 3, 2, buffer);
314
tft.setCursor(15, 6+23+vTextShift);
315
tft.print(buffer);
316
tft.setTextColor(RED);
317
dtostrf(ptopV, 3, 2, buffer);
318
tft.setCursor(15, 6+23+vTextShift);
319
tft.print(buffer);
320
OldptopV=ptopV;
321
}
322
if
(theFreq!=OldtheFreq){
323
tft.setTextColor(BLACK);
324
dtostrf(OldtheFreq, 5, 0, buffer);
325
tft.setCursor(0, 16+53+vTextShift);
326
tft.print(buffer);
327
tft.setTextColor(RED);
328
dtostrf(theFreq, 5, 0, buffer);
329
tft.setCursor(0, 16+53+vTextShift);
330
tft.print(buffer);
331
OldtheFreq=theFreq;
332
}
333
/*if (useThreshold == 0) {
334
tft.setCursor(15, 8+29+vTextShift);
335
tft.print("Off");
336
} else if (useThreshold == 1) {
337
tft.setCursor(15, 8+29+vTextShift);
338
tft.print("Rise");
339
dtostrf((float) (theThreshold>>2) * voltageConst, 3, 2, buffer);
340
} else if (useThreshold == 2) {
341
tft.setCursor(15, 8+29+vTextShift);
342
tft.print("Fall");
343
dtostrf((float) (theThreshold>>2) * voltageConst, 3, 2, buffer);
344
}
345
tft.setCursor(11, 10+35+vTextShift);
346
tft.print(buffer);*/
347
// Correctly format the text so that there are always 4 characters
348
if
(timePeriod!=OldtimePeriod){
349
tft.setTextColor(BLACK);
350
if
(OldtimePeriod < 400) {
351
dtostrf((
float
) OldtimePeriod/1000 * 25, 3, 2, buffer);
352
}
else
if
(OldtimePeriod < 4000) {
353
dtostrf((
float
) OldtimePeriod/1000 * 25, 3, 1, buffer);
354
}
else
if
(OldtimePeriod < 40000) {
355
dtostrf((
float
) OldtimePeriod/1000 * 25, 3, 0, buffer);
356
}
else
{
// Out of range
357
dtostrf((
float
) 0.00, 3, 2, buffer);
358
}
359
tft.setCursor(15, 12+41+vTextShift);
360
tft.print(buffer);
361
362
tft.setTextColor(RED);
363
if
(timePeriod < 400) {
364
dtostrf((
float
) timePeriod/1000 * 25, 3, 2, buffer);
365
}
else
if
(timePeriod < 4000) {
366
dtostrf((
float
) timePeriod/1000 * 25, 3, 1, buffer);
367
}
else
if
(timePeriod < 40000) {
368
dtostrf((
float
) timePeriod/1000 * 25, 3, 0, buffer);
369
}
else
{
// Out of range
370
dtostrf((
float
) 0.00, 3, 2, buffer);
371
}
372
tft.setCursor(15, 12+41+vTextShift);
373
tft.print(buffer);
374
OldtimePeriod=timePeriod;
375
}
376
/*if (voltageRange == 1) {
377
tft.setCursor(7, 18+59+vTextShift);
378
tft.print("0-3.30");
379
} else if (voltageRange == 2) {
380
tft.setCursor(7, 18+59+vTextShift);
381
tft.print("0-1.65");
382
} else if (voltageRange == 3) {
383
tft.setCursor(7, 18+59+vTextShift);
384
tft.print("0-0.83");
385
} */
386
}
387
void
drawT(
void
) {
388
char
buffer[16];
389
tft.fillRect(0,vTextShift+5,45,150,BLACK);
390
tft.setTextColor(RED);
391
tft.setTextSize(1);
392
tft.setCursor(0, 5+vTextShift);
393
tft.print(
"Av"
);
394
tft.setCursor(0, 2+11+vTextShift);
395
tft.print(
"Mx"
);
396
tft.setCursor(0, 4+17+vTextShift);
397
tft.print(
"Mn"
);
398
tft.setCursor(0, 6+23+vTextShift);
399
tft.print(
"PP"
);
400
tft.setCursor(0, 8+29+vTextShift);
401
tft.print(
"Th"
);
402
tft.setCursor(0, 10+35+vTextShift);
403
tft.print(
"V"
);
404
tft.setCursor(0, 12+41+vTextShift);
405
tft.print(
"Tm"
);
406
tft.setCursor(4, 14+47+vTextShift);
407
tft.print(
"ms/div"
);
408
tft.setCursor(31, 16+53+vTextShift);
409
tft.print(
"Hz"
);
410
tft.setCursor(0, 18+59+vTextShift);
411
tft.print(
"R"
);
412
413
// Draw dynamic text
414
if
(autoHScale ==
true
) {
415
tft.setCursor(120, 2);
416
tft.print(
"A"
);
417
}
418
dtostrf(avgV, 3, 2, buffer);
419
tft.setCursor(15, 5+vTextShift);
420
tft.print(buffer);
421
422
dtostrf(maxV, 3, 2, buffer);
423
tft.setCursor(15, 2+11+vTextShift);
424
tft.print(buffer);
425
426
dtostrf(minV, 3, 2, buffer);
427
tft.setCursor(15, 4+17+vTextShift);
428
tft.print(buffer);
429
430
dtostrf(ptopV, 3, 2, buffer);
431
tft.setCursor(15, 6+23+vTextShift);
432
tft.print(buffer);
433
434
dtostrf(theFreq, 5, 0, buffer);
435
tft.setCursor(0, 16+53+vTextShift);
436
tft.print(buffer);
437
438
if
(useThreshold == 0) {
439
tft.setCursor(15, 8+29+vTextShift);
440
tft.print(
"Off"
);
441
}
else
if
(useThreshold == 1) {
442
tft.setCursor(15, 8+29+vTextShift);
443
tft.print(
"Rise"
);
444
dtostrf((
float
) (theThreshold>>2) * voltageConst, 3, 2, buffer);
445
}
else
if
(useThreshold == 2) {
446
tft.setCursor(15, 8+29+vTextShift);
447
tft.print(
"Fall"
);
448
dtostrf((
float
) (theThreshold>>2) * voltageConst, 3, 2, buffer);
449
}
450
tft.setCursor(11, 10+35+vTextShift);
451
tft.print(buffer);
452
// Correctly format the text so that there are always 4 characters
453
if
(timePeriod < 400) {
454
dtostrf((
float
) timePeriod/1000 * 25, 3, 2, buffer);
455
}
else
if
(timePeriod < 4000) {
456
dtostrf((
float
) timePeriod/1000 * 25, 3, 1, buffer);
457
}
else
if
(timePeriod < 40000) {
458
dtostrf((
float
) timePeriod/1000 * 25, 3, 0, buffer);
459
}
else
{
// Out of range
460
dtostrf((
float
) 0.00, 3, 2, buffer);
461
}
462
tft.setCursor(15, 12+41+vTextShift);
463
tft.print(buffer);
464
if
(voltageRange == 1) {
465
tft.setCursor(7, 18+59+vTextShift);
466
tft.print(
"0-3.30"
);
467
}
else
if
(voltageRange == 2) {
468
tft.setCursor(7, 18+59+vTextShift);
469
tft.print(
"0-1.65"
);
470
}
else
if
(voltageRange == 3) {
471
tft.setCursor(7, 18+59+vTextShift);
472
tft.print(
"0-0.83"
);
473
}
474
OlduseThreshold = useThreshold;
475
OldtheThreshold = theThreshold;
476
OldtimePeriod = timePeriod;
477
OldavgV = avgV;
478
OldmaxV = maxV;
479
OldminV = minV;
480
OldptopV = ptopV;
481
OldtheFreq = theFreq;
482
}
483
484
void
draw(
void
) {
485
tft.fillScreen(BLACK);
486
drawT();
487
draw1();
488
}
489
490
void
draw1(
void
) {
491
int
i,j;
492
// tft.drawFastVLine((128-numOfSamples), 0, 63, ST7735_YELLOW);
493
if
(useThreshold != 0)
494
for
(i=0; i<numOfSamples; i+=3){
495
tft.drawPixel(i,63-(theThreshold>>2),YELLOW);
496
tft.drawPixel(i,63,YELLOW);
497
}
498
j=numOfSamples/4;
499
for
(i=0; i<63; i+=5) {
500
tft.drawPixel(0,i,YELLOW);
501
tft.drawPixel(j,i,YELLOW);
502
tft.drawPixel(j+j,i,YELLOW);
503
tft.drawPixel(j+j+j,i,YELLOW);
504
tft.drawPixel(numOfSamples-1,i,YELLOW);
505
}
506
tft.drawLine(0,adcOldReadings[0],1,adcOldReadings[1], BLACK);
507
for
(i=1; i<numOfSamples-1; i++){
// Draw using lines
508
tft.drawLine(i,adcOldReadings[i],i+1,adcOldReadings[i+1], BLACK);
509
tft.drawLine(i-1,adcReadings[i-1],i,adcReadings[i], WHITE);
510
adcOldReadings[i-1]=adcReadings[i-1];
511
}
512
tft.drawLine(numOfSamples-2,adcReadings[numOfSamples-2],i,adcReadings[numOfSamples-1], WHITE);
513
adcOldReadings[numOfSamples-2]=adcReadings[numOfSamples-2];
514
adcOldReadings[numOfSamples-1]=adcReadings[numOfSamples-1];
515
}
516
517
void
setup
() {
518
Serial
.begin(9600);
519
tft.reset();
520
tft.initDisplay();
521
tft.setRotation(1);
522
tft.fillScreen(BLACK);
523
// Turn on LED backlight
524
//analogWrite(3, ledBacklight);
525
526
#if FASTADC
527
// set prescale to 16
528
sbi(ADCSRA,ADPS2) ;
529
cbi(ADCSRA,ADPS1) ;
530
cbi(ADCSRA,ADPS0) ;
531
#endif
532
delay(100);
533
draw();
534
}
535
536
int
j=8;
537
538
void
loop
() {
539
540
collectData();
541
draw1();
542
drawD();
543
if
(j==100){
544
drawT();
545
j=0;
546
}
547
j++;
548
549
// If user sends any serial data, show menu
550
if
(
Serial
.available() > 0) {
551
handleSerial();
552
}
553
554
// rebuild the picture after some delay
555
delay(100);
556
}
На картинке наводка 50hz