Мини осциллограф Arduino на LCD 5110

pooller
Offline
Зарегистрирован: 13.04.2014

Доброго времени суток всем!

Накопал в сети интересный девайс -осциллограф на ARDUINO

У меня как раз завалялись дома Arduino Pro Mini 328 - 3.3V/8MHz и графический LCD дисплей Nokia 5110 для Arduino

залил этот скетч:

01/*
02 ###########################################################
03 Title:       Arduino Oscilloscope
04 Purpose:     Use a Nokia 3310 GLCD screen with the arduino
05 Created by:  Fileark. see Fileark.com for more info.
06 Note:        Please reuse, repurpose, and redistribute this code.
07 Note:        This code uses the Adafruit PDC8544 LCD library 
08 ###########################################################
09 */
10 
11#include <Adafruit_GFX.h>
12#include <Adafruit_PCD8544.h>
13 
14// pin 7 - Serial clock out (SCLK)
15// pin 6 - Serial data out (DIN)
16// pin 5 - Data/Command select (D/C)
17// pin 4 - LCD chip select (CS)
18// pin 3 - LCD reset (RST)
19Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
20 
21 
22// a bitmap of a 16x16 fruit icon
23static 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
28 
29int channelAI = A0;      // select the input pin for the Oscilioscope
30int scaleYAI = A1;       // select the input pin for the Y (horizontal) potentiometer
31int scaleXAI = A2;       // select the input pin for the X (Vertical) potentiometer
32 
33int delayVariable = 0;   // define a variable for the Y scale / delay
34int xVariable = 0;       // define a variable for the x scale
35int yCtr = 0;            // define a variable for the y counter used to collect y position into array
36int posy = 0;            // define a variable for the y position of the dot
37int myArray[85];         // define an array to hold the data coming in
38 
39 
40void setup(void)
41{
42  Serial.begin(9600);
43  display.begin();
44  // init done
45  // you can change the contrast around to adapt the display
46  // for the best viewing!
47  display.setContrast(40);
48  delay(2000);
49  display.clearDisplay();   // clears the screen and buffer
50}
51 
52void loop()
53
54  delayVariable = analogRead(scaleYAI);
55  delayVariable = (delayVariable/50);
56  xVariable = analogRead(scaleXAI);
57  xVariable = (xVariable/22);
58 
59  for(yCtr = 0; yCtr < 85; yCtr += 1)   // the for loop runs from 0 and < 85, it fills the array with 84 records
60  {                                
61    posy = analogRead(channelAI);       // read the value from the sensor:
62    myArray[yCtr] = (posy/xVariable);   // scale the value based on the x scale potentiometer     
63    delay (delayVariable);           // scale the y collection of data using the delay from the y potentiometer  
64  }
65 
66  yCtr == 0;                           // set the counter to zero so we can use it again
67  display.clearDisplay();                        // clear the LCD screen so we can draw new pixels
68 
69  for(yCtr = 0; yCtr < 85; yCtr += 1)  // for loop runs 84 times
70  {
71    display.drawPixel(yCtr, myArray[yCtr], BLACK); // draw the 84 pixels on the screen
72  }
73 
74  display.display();                     // show the changes to the buffer
75  yCtr == 0;                           // set the counter to zero so we can use it again
76 
77}
Подключил дисплей как на картинке
все заработало, но на экране нет ни частоты ни амплитуды
 
Порылся еще в сети и нарыл осциллограф с другим экраном от NOKIA 3310
Но тут уже все отображается и частота и амплитуда 
скетч: 
001#include "U8glib.h"
002#include <EEPROM.h>
003  
004// Variables you might want to play with
005byte useThreshold = 1;                  // 0 = Off, 1 = Rising, 2 = Falling
006byte theThreshold = 128;                // 0-255, Multiplied by voltageConst
007unsigned int timePeriod = 200;          // 0-65535, us or ms per measurement (max 0.065s or 65.535s)
008byte voltageRange = 1;                  // 1 = 0-3.3V, 2 = 0-1.65V, 3 = 0-0.825V
009byte ledBacklight = 100;
010  
011boolean autoHScale = true;             // Automatic horizontal (time) scaling
012boolean linesNotDots = true;            // Draw lines between data points
013  
014// Variables that can probably be left alone
015const byte vTextShift = 3;              // Vertical text shift (to vertically align info)
016const byte numOfSamples = 100;          // Leave at 100 for 128x64 pixel display
017unsigned int HQadcReadings[numOfSamples];
018byte adcReadings[numOfSamples];
019byte thresLocation = 0;                 // Threshold bar location
020float voltageConst = 0.052381;          // Scaling factor for converting 0-63 to V
021float avgV = 0.0;   
022float maxV = 0.0;
023float minV = 0.0;
024float ptopV = 0.0;
025float theFreq = 0;
026  
027const byte theAnalogPin = 7;             // Data read pin
028  
029const byte lcdLED = 6;                   // LED Backlight
030const byte lcdA0 = 7;                    // Data and command selections. L: command  H : data
031const byte lcdRESET = 8;                 // Low reset
032const byte lcdCS = 9;                    // SPI Chip Select (internally pulled up), active low
033const byte lcdMOSI = 11;                 // SPI Data transmission
034const byte lcdSCK = 13;                  // SPI Serial Clock
035  
036// SW SPI:
037//U8GLIB_MINI12864 u8g(lcdSCK, lcdMOSI, lcdCS, lcdA0, lcdRESET);
038// HW SPI:
039U8GLIB_MINI12864 u8g(lcdSCK, lcdMOSI, lcdCS, lcdA0, lcdRESET);
040  
041// High speed ADC code
043#define FASTADC 1
044// defines for setting and clearing register bits
045#ifndef cbi
046#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
047#endif
048#ifndef sbi
049#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
050#endif
051  
052void collectData(void) {
053  unsigned int tempThres = 0;
054  unsigned int i = 0;
055  
056  if (autoHScale == true) {
057    // With automatic horizontal (time) scaling enabled,
058    // scale quickly if the threshold location is far, then slow down
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;
067    }
068  }
069  // Enforce minimum time periods
070  if (timePeriod < 35) {
071    timePeriod = 35;
072  }
073    
074  // Adjust voltage contstant to fit the voltage range
075  if (voltageRange == 1) {
076    voltageConst = 0.0523810; // 0-3.30V
077  } else if (voltageRange == 2) {
078    voltageConst = 0.0261905; // 0-1.65V
079  } else if (voltageRange == 3) {
080    voltageConst = 0.0130952; //0-0.825V
081  }
082    
083  // If using threshold, wait until it has been reached
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++;
090  }
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++;
094  }
095  
096  // Collect ADC readings
097  for (i=0; i<numOfSamples; i++) {
098    // Takes 35 us with high speed ADC setting
099    HQadcReadings[i] = analogRead(theAnalogPin);
100    if (timePeriod > 35)
101      delayMicroseconds(timePeriod-35);
102  }
103  for (i=0; i<numOfSamples; i++) {
104    // Scale the readings to 0-63 and clip to 63 if they are out of range.
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;
114    }
115    // Invert for display
116    adcReadings[i] = 63-adcReadings[i];
117  }
118    
119  // Calculate and display frequency of signal using zero crossing
120  if (useThreshold != 0) {
121     if (useThreshold == 1) {
122        thresLocation = 1;
123        while ((adcReadings[thresLocation]<(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
124        thresLocation++;
125        while ((adcReadings[thresLocation]>(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
126     }
127     else if (useThreshold == 2) {
128        thresLocation = 1;
129        while ((adcReadings[thresLocation]>(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
130        thresLocation++;
131        while ((adcReadings[thresLocation]<(63-(theThreshold>>2))) && (thresLocation<numOfSamples-1)) (thresLocation++);
132     }
133  
134     theFreq = (float) 1000/(thresLocation * timePeriod) * 1000;
135  }
136    
137  // Average Voltage
138  avgV = 0;
139  for (i=0; i<numOfSamples; i++)
140     avgV = avgV + adcReadings[i];
141  avgV = (63-(avgV / numOfSamples)) * voltageConst;
142  
143  // Maximum Voltage
144  maxV = 63;
145  for (i=0; i<numOfSamples; i++)
146     if (adcReadings[i]<maxV) maxV = adcReadings[i];
147  maxV = (63-maxV) * voltageConst;
148  
149  // Minimum Voltage
150  minV = 0;
151  for (i=0; i<numOfSamples; i++)
152     if (adcReadings[i]>minV) minV = adcReadings[i];
153  minV = (63-minV) * voltageConst;
154  
155  // Peak-to-Peak Voltage
156  ptopV = maxV - minV;
157}
158  
159void handleSerial(void) {
160  char inByte;
161  char dataByte;
162  boolean exitLoop = false;
163  do {
164    // Clear out buffer
165    do {
166      inByte = Serial.read();
167    } while (Serial.available() > 0);
168    
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");
189      
190    // Wait for input/response, refresh display while in menu
191    do {
192      collectData();
193      // Picture Display Loop
194      u8g.firstPage(); 
195      do { draw(); } while( u8g.nextPage() );
196    } while (Serial.available() == 0);
197    inByte = Serial.read();
198      
199    if (inByte == '1') {
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");
265      exitLoop = true;
266    }
267  } while (exitLoop == false);
268}
269  
270void draw(void) {
271  int i;
272  char buffer[16];
273    
274  u8g.setFont(u8g_font_micro);
275    
276  // Draw static text
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");
287    
288  // Draw dynamic text
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);
308  }
309  u8g.drawStr(8, 35+vTextShift, buffer);
310  // Correctly format the text so that there are always 4 characters
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);
317  } else { // Out of range
318    dtostrf((float) 0.00, 3, 2, buffer);
319  }
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");
327  }
328    
329  // Display graph lines
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) {
335     u8g.drawPixel(53,i);
336     u8g.drawPixel(78,i);
337     u8g.drawPixel(103,i);
338     u8g.drawPixel(127,i);
339  }
340  // Threshold bar
341  for (i=0; i<63; i+=3)
342     u8g.drawPixel(thresLocation+(128-numOfSamples),i);
343  // Draw ADC readings
344  if (linesNotDots == true) {
345    for (i=1; i<numOfSamples; i++) // Draw using lines
346      u8g.drawLine(i+(128-numOfSamples)-1,adcReadings[i-1],i+(128-numOfSamples),adcReadings[i]);
347  } else {
348    for (i=2; i<numOfSamples; i++) // Draw using points
349      u8g.drawPixel(i+(128-numOfSamples),adcReadings[i]);
350  }
351}
352  
353void setup() {
354  u8g.begin();
355  Serial.begin(9600);
356    
357  // Turn on LED backlight
358  analogWrite(lcdLED, ledBacklight);
359    
360  #if FASTADC
361    // set prescale to 16
362    sbi(ADCSRA,ADPS2) ;
363    cbi(ADCSRA,ADPS1) ;
364    cbi(ADCSRA,ADPS0) ;
365  #endif
366  delay(100);
367}
368  
369void loop() {
370  collectData();
371  // Picture Display Loop
372  u8g.firstPage(); 
373  do { draw(); } while( u8g.nextPage() );
374  
375  // If user sends any serial data, show menu
376  if (Serial.available() > 0) {
377    handleSerial();
378  }
379  
380  // rebuild the picture after some delay
381  delay(100);
382}

Если кто знает как переделать этот скетч 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)

Помогите разобраться, я уже себе весь мозг проел

 
 
pooller
Offline
Зарегистрирован: 13.04.2014

вот так этот девайс должен работать

http://semifluid.com/wp-content/uploads/2013/05/MVI_4205.mp4.mp4

danny222
Offline
Зарегистрирован: 16.04.2014

U8GLIB универсальная библиотека вроде как)

const byte lcdLED = 6;                   // LED Backlight
const byte lcdA0 = 9;                    // Data and command selections. L: command  H : data
const byte lcdRESET = 8;                 // Low reset
const byte lcdCS = 10;                    // SPI Chip Select (internally pulled up), active low
const byte lcdMOSI = 11;                 // SPI Data transmission
const byte lcdSCK = 13;                  // SPI Serial Clock
 
U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8
 
с 29 по 39 строку в твоем примере
 
Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

При беглом осмотре, в 66 строке   yCtr == 0; // set the counter to zero so we can use it

Может там должно быть присваивание?

Geronimo
Offline
Зарегистрирован: 06.05.2013

Не имеет значения, следом идет цикл который сбросит в 0. Строка ничего не делает полезного или вредного.

dtvims
Offline
Зарегистрирован: 26.11.2012

Ключевое - это заменить U8GLIB_MINI12864 на U8GLIB_PCD8544

1const byte lcdLED = 6;                   // LED Backlight
2const byte lcdA0 = 7;                    // D/C - Data and command selections. L: command  H : data
3const byte lcdRESET = 8;                 // RST- Low reset
4const byte lcdCS = 9;                    // SCE - SPI Chip Select (internally pulled up), active low
5const byte lcdMOSI = 11;                 // DIN(MOSI) - SPI Data transmission
6const byte lcdSCK = 13;                  // SCK - SPI Serial Clock

а вот дальше начинаются проблемы, что разрешение экрана меньше чем надо :(

На фото дисплей 5110 с последней программой, а на дуине замкнут adc7 с d0(rx), таким образом на вход осцилографа подается сигнал с uart'а, куда бегут с компа буковки "а".

dtvims
Offline
Зарегистрирован: 26.11.2012

Был у меня дисплейчик побольше и за ту же цену, что 5110, см. http://we.easyelectronics.ru/lcd_gfx/podklyuchenie-tft-displeya-k-avr.html

Дисплей больше разрешением, даже чем тот, что в оригинальном примере, да еще и цветной. Правда ардуинка слишком медленно расчеты делает для вывода на экран, пришлось весь вывод на экран значительно переработать, стало приемлимо и красиво :) На экране ШИМ подсветки этого же дисплея.

Если кому понадобится, выложу код для данного дисплея.

pooller
Offline
Зарегистрирован: 13.04.2014

Сегодня приобрел вот такой экранчик:

 
Может кто знает как его подключить к этой схеме?
я уже устал ломать себе голову и издеваться над гуглом
 
 
 
dtvims
Offline
Зарегистрирован: 26.11.2012

По первой Вашей ссылке подключение. Передача данных по 8бит D0-D7. Последовательность инициализаци надо искать в даташите. Далее надо экспериментировать. В основном все покупают для подобных поделок дисплеи уже на плате с простым интерфейсом spi, а поскольку сразу все делают так, то и инфы на такие дисплеи больше.

pooller
Offline
Зарегистрирован: 13.04.2014

Я даже не задумывался, что возникнут такие сложности в подключении этого дисплея.

для подключения этого дисплея нужно применить ету схему? Я правильно понял? 

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

 

dtvims
Offline
Зарегистрирован: 26.11.2012

Вариант Вы написали правильно, вот только Ваш дисплей в Возможно совместимых с данной библиотекой.

Есть вот такая темка http://forum.arduino.cc/index.php/topic,134689.0.html - может чем поможет.

pooller
Offline
Зарегистрирован: 13.04.2014

у меня для такого подключения не хватит ног на ардуине

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

почему не хватит? хватает же

pooller
Offline
Зарегистрирован: 13.04.2014

Если не трудно напишина какие ноги этот экран мне подключать? Там ведь есть и 16, 17,18 но на моей дуине такого нет(( 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

пины можно любые настроить для доп. управляющих. для основных из одного порта должно быть. тоесть оставляете как есть

а вот 16 17 18 меняете на свои

я бы так сделал. как в либе сделано надо смотреть

попробуйте проще. меняете на любые доступные и проверьте.

я не нашел соответствия одному порту на меге328 и 2560 для выводов данных. может и проглядел, но лучше проверье тупо вставляя свои пины

 

dtvims
Offline
Зарегистрирован: 26.11.2012

Идеально d0-d7 подключить целиком на 1 порт atmega, а остальные любые, ну кроме тех, что используются. Кстати, так и передача данных будет быстрее, чем по spi. Если ардуино на меге вроде 328-й то целиком ни одного порта не получается:  на PORTB сидит кварц, на С находится ADC, на D сидит UART, т.е. для идеала надо что-то более многоногое :(

Пинов должно хватить в любом случае. Только лучше базовый доступ к дисплею свой делать. Кстати, под переделку лучше использовать библиотеку adafruit, там на, мой взгляд, понятнеее что переписывать надо. Собственно, я на нее все и переделал себе, плюс немного оптимизации и получилось очень даже ничего :)

pooller
Offline
Зарегистрирован: 13.04.2014

Еще немного и я разобью этот дисплей об ету ардуину. 

Хоть как то бы подключить уже. Я уже задолбался, мозг пухнет

dtvims
Offline
Зарегистрирован: 26.11.2012

С таким подходом у Вас ничего не получится :(

С первого раза редко, что получается. Почитайте обсуждения профессионалов, которые говорят: подозрительно, что у меня все сразу заработало.

Поэтому самое оптимальное брать примеры, которые заведомо работают и повторять их. Для этого Вам надо для начала, прикупить дисплей, на который есть готовые примеры, а потом уже данный мучать, со знанием дела...

pooller
Offline
Зарегистрирован: 13.04.2014

Это у меня от того что я в тупик уткнулся, эмоции полезли мучать этот дисплей я то буду пока у меня не получится. Решил подключать по 8 бит, пока перепаял все провода, потом подключил и не чего не произошло. Дисплей как лежал без признаков жизни так и продолжал спокойно лежать. Я до трех часов ночи издевался над гуглом и над дисплеем, пока сам не выключился

Там на дисплее, как оказалось еще перемычка есть. Последовательный или паралельный 

 

dtvims
Offline
Зарегистрирован: 26.11.2012

Давайте переключим на последовательный режим и тогда ему будет соответствовать один из методов подключения 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

pooller
Offline
Зарегистрирован: 13.04.2014

Вот спасибо за помощь. Хоть какой то сдвиг в этом деле. Я в тупик уже залез, не знал уже что дальше делать. Все идеи закончились. Сегодня приеду с работы домой, Сразу попробую подключить, так как вы написали.

dtvims
Offline
Зарегистрирован: 26.11.2012

Еще дополнение:

U8GLIB_NHD_C12864(sck, mosi, cs, a0 [, reset])  - Вариант SW SPI - програмный SPI

U8GLIB_NHD_C12864(cs, a0 [, reset]) - Вариант HW SPI - Хардварный. Разумеется - это лучше, потому как быстрее, только SCLK и MOSI подключаются строго на 11-й и 13-й пины дудки, см. примеры.

RESET - необязателен, его можно замкнуть с ресетом дуинки.

pooller
Offline
Зарегистрирован: 13.04.2014

подключил так, как вы написали. Не заработало (

Кто то не правильный или ардуинка или дисплей или я))

Завтра с самого утра займусь с начала проверять все что наподключал. Где то должен быть какой то косяк. Ардуинку проверял только что на дисплее от 5110 - все работает. Вот только заметил какие то крадковременные подвисания при работе программы осциллографа. может они и ранее были а я не замечал их. 

dtvims
Offline
Зарегистрирован: 26.11.2012

Подключение пинов я написал как написано в даташите. Мог пропустить какую-то деталь. Потом класс из библиотеки u8glib, совместим условно с Вашим дисплеем и может не стартовать из-за какой-нибудь пропущенной мелочи в инициализации, или может Вы пины на шлейфе не в ту сторону нумировали? Режим точно последовательный включили? Я в свое время долго мучал протокол ps/2 где в зависимости от компа идет разная инициализация устройства и если все не предусмотреть, то ничего и не работает и непонятно куда девается "искра внутреннего сгорания", потом все-таки нашел...

Подвисания и должны быть. Между обновлениями дисплея он делает всю пачку измерений. Если масштаб используется для высокой частоты, то измерения делаются без задержек, если низкой частоты, то чтобы не отображать одну прямую, делаются искуственные задержки между измерениями, вот и получается весьма заметная задержка.

pooller
Offline
Зарегистрирован: 13.04.2014

А при неправильной библиотеке на экране должно что то появляться? Просто сколько я не экспериментировал, диспей лежит без всяких признаков жизни, кроме подсветки

dtvims
Offline
Зарегистрирован: 26.11.2012

Чтобы что-то изменилось, нужна правильная последовательность инициализации. Если выбран неверно метод, дисплей не заработает. Надо курить внимательно даташит, ссылка выше. Но опять же, даташит верен, если верно указан контроллер монитора по Вашим ссылкам, бывает заказываешь одно, а там что-то поменяли на аналог... Попробуйте разобраться в даташите, проинициализируйте spi самостоятельно, и инициадизируйте дисплей по даташиту. Потренироваться можно на дисплее, который Вам уже получилось включить, просто, чтобы понять, что все делаете правильно.

pooller
Offline
Зарегистрирован: 13.04.2014

Подключал всеми способами (последовательным, параллельным) загружал все доступные мне библиотеки, и ни чего у меня не получилось. Лежит мой дисплей, без признаков жизни, хоть бы какую нибудь ерунду показал. А так, кроме подсветки ни чего не выдал. Буду мучать гугл, может там что накопаю.

dtvims
Offline
Зарегистрирован: 26.11.2012

Интересно, что вот тут 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.

pooller
Offline
Зарегистрирован: 13.04.2014

а на такой дисплей 2,4" TFT LCD Touch shield

возможно установить осциллограф? 

я пытался воткнуть в скетч осциллографа библиотеки этого дисплея, что то у меня ни чего не вышло

dtvims
Offline
Зарегистрирован: 26.11.2012

А Вы примеры с ним просто отдельно пробовали?

Просто так работать не будет, надо переделывать всю работу с дисплеем из осцилографа.

Например, я убрал инициализацию u8g полностью и поставил вместо него свой класс с другим именем переменной, типа tft, потом заменил все вхождения методов из u8g на аналогичные методы из своего tft. При полной замене завелось сразу, только шрифты разъехались. Затем перерасчитал где и что выводить, чтобы выводилось более красиво. Затем стал оптимизировать вывод на дисплей, чтобы искличить моргание при перерисовке, чтобы все красиво и быстро работало.

pooller
Offline
Зарегистрирован: 13.04.2014

Я не правильно вопрос задал, но ответ получил именно тот, который и хотел услышать)))

пример с ним есть у меня рабочий рисовалка 

там к этому дисплею несколько библиотек есть но некоторые не могу запустить, какую то ошибку выдают при компиляции я погуглил, так и не понял, что он от меня хочет. А рисовалка запустилась нормально. Сын часа на два завис в рисовании на экране))) 

pooller
Offline
Зарегистрирован: 13.04.2014

я наивно думал, что можно скопировать ту часть скетча, где идет инициализация дисплея в скетч осциллографа и все заработает. 

pooller
Offline
Зарегистрирован: 13.04.2014

А можешь выложить свой скетч, со своим цветным дисплеем? Я попробую разобраться, что нужно изменить под библиотеку своего LCD 

 

dtvims
Offline
Зарегистрирован: 26.11.2012

Ну, например было u8g.drawStr(12, 17+vTextShift, buffer);

а надо tft.text(12, 17+vTextShift, buffer); - Это гипотетический пример. может быть разбито на 2 разных команды, типо установки координат, а отдельно вывод текста. См. Класс для Вашего дисплея.

UPD. Неудержался и заказал себе такой же дисплейчик. Недели через 2 перепишу код под него :)

pooller
Offline
Зарегистрирован: 13.04.2014

Я сам не удержался от покупки этого дисплейчика. Пока экспериментировал с подключением жки128x64 к ардуине случайно раздавил свой экран от нокии 5110. полез искать новый и купил 2,4" TFT LCD Touch shield и еще arduino uno к нему

dtvims
Offline
Зарегистрирован: 26.11.2012

Я сейчас хочу повторить данный осцилограф на stm32, по шустре будет в 4 раза. Думал убрать управление по uart'у и заменить на меню на дисплее и несколько кнопок. Тачскрин же прилично расширяет возможности, уже никакие кнопки делать не надо. Жаль только, что ждать придется, но цена вкусная :)

Меня смущает для ардуино, что дисплей сожрал почти все ноги.

Immortal
Offline
Зарегистрирован: 28.12.2013

dtvims, получилось что то на stm32 ?

Первоисточник второго показометра: http://www.semifluid.com/2013/05/28/arduino-fio-lcd-oscilloscope/

dtvims
Offline
Зарегистрирован: 26.11.2012

Получилось первое приближение с мониторчиком 5110, в режиме "все на авто, от 0 до 3.3В". От ADC у STM32 я ожидал большего. http://rukodelie-ds.ru/forum/viewtopic.php?f=13&t=734#p972 - тут пока кривое, но работающее решение.

Сейчас, приостановил эксперименты, т.к. занят и жду сенсорный дисплейчик (см.выше), что должен вот-вот приехать.

Immortal
Offline
Зарегистрирован: 28.12.2013

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-скетч под такой экран?

dtvims
Offline
Зарегистрирован: 26.11.2012

Да, справа все тот же экран, что я показывал тут на форуме, я его с ардуиной брал за эталон. Собственно источником сигнала служит шим с той же дуинки, через резистор, с парой кондесаторов на землю (можно их увидеть между дисплеями). Смотрел чтобы вид сигнала и расчет частоты были похожи. Конечно о какой-то точности говорить не приходится, калибровать просто не на чем :(

С точки зрения конкретного кода, что я сделал для stm32, то под другой дисплей надо переделать только 3 функции: вывод пикселя, вывод текста и очистку экрана. Но это решит только проблему взаимодействия с экраном. Больше по размеру и добавление цветов у др. дисплея, означает, что надо гнать больше данных по spi, что может сильно отразиться на скорости отображения и может появится сильно заметное мерцание, вот тут понадобится доп. оптимизация с отрисовкой. Я такую оптимизацию провел для дуинки: изменил функцию отрисовки линий с учетом конкретной задачи, стал обновлять только изменения (текст, только тот что изменился, лини стирать старые и сразу рисовать новые). Вариант настроек по usart'у меня как-то не очень устраивает, потому дальше надеюсь сделать на сенсорном экране меню с настройками. Еже хочу включить второй adc,  создать виртуальный usb-comport и гнать по нему данные вреальном времени, чтобы обрабатывать цифровые сигналы - эх, мечты...

 

P.s. а зачем Вам преобразователь уровней? Запускайте все на 3.3В! Stm32 так вообще на этом напряжении работает, дисплей тоже...

Immortal
Offline
Зарегистрирован: 28.12.2013

dtvims пишет:

а зачем Вам преобразователь уровней? Запускайте все на 3.3В! Stm32 так вообще на этом напряжении работает

Я думал его сначала на ардуине запустить. Знаю, что будет медленно - у меня уже есть 128x160 на ST7735S и он мерцает, при большем разрешении частота обновления упадет еще сильнее.

Stm32 у меня пока нету, выбираю какую плату заказать.

 

dtvims
Offline
Зарегистрирован: 26.11.2012

На ардуине должен быть переключатель или джампер, переводящий весь контроллер на питание от 3.3В.

Upd. Посмотрел на официальные платки и понял, что по ходу обладателями заветными переключателями или джамперами являются те кто купил или стронние аналоги или дешевые подделки - что-то тут не так :)

Immortal
Offline
Зарегистрирован: 28.12.2013

dtvims пишет:

Был у меня дисплейчик побольше и за ту же цену, что 5110, см. http://we.easyelectronics.ru/lcd_gfx/podklyuchenie-tft-displeya-k-avr.html

Если кому понадобится, выложу код для данного дисплея.

Интересно было бы посмотреть на код, у меня такой же экран.

dtvims пишет:

На ардуине должен быть переключатель или джампер, переводящий весь контроллер на питание от 3.3В.

3.3В найти не проблема. У меня есть и платка стабилизатора и мой "программатор" CP2102 имеет отдельные выводы с 3.3 и 5В

dtvims
Offline
Зарегистрирован: 26.11.2012

Для ST7735 я использовал библиотеку Adafruit и для нее доп. библиотеку Adafruit_ST7735. В последней кое что поменял/добавил "Adafruit_ST7735.cpp":

01void 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 и только для быстрой отрисовки вертикальных линий отрисованных слева на право, во всех других случаях скорее всего будет рисоваться не корректно, но для конкретной задачи дает значительное ускорение.

Ну и сам код как-то  так:

Настройка "соединять линиями или отображать точками" полностью отключена, только линиями рисуем. На 3-м пине ШИМ, который я подключал не к дисплею (вообше шимом напрямую лучше дисплей не подсвечивать, а давать питание на дисплей напрямую от источника питания), а через резистор в несколько килоОм к пину ADC, теперь Если между ADC и землей поставить конденсатор на 0.1мкф, то на графике получается красивое сглаживание :)

P.s. Забрал сегодня с почты сенсорный дисплей. Прикольная штука, жаль, что немного поцарапаный оказался :(, причем НЕ нашей почтой, ибо упакован был так, что выдержал бы взрыв :), с другой стороны всего около 8 баксов с доставкой.

UPD. В дисплейчике для согласования уровней используется логика hc245. Поискал в продаже, окалось, достаточно дешевый чип и есть в наличии. Можно использовать :)

Immortal
Offline
Зарегистрирован: 28.12.2013

Спасибо, попробую на своем экранчике вечером. А в закомментированных фрагментах №2 и 3, что там за логика?

dtvims
Offline
Зарегистрирован: 26.11.2012

Это я не стал делать отрисовку текста, что меняется только от настроек

Immortal
Offline
Зарегистрирован: 28.12.2013

Мини осциллограф работает отлично. Т.к. я уже наигрался с ST7735 низкая частота обновления экрана не огорчила.

Чувствую, пора заказывать экран с параллельным интерфейсом и Stm32 дискавери или другую плату АРМом и быстрым АЦП

dtvims
Offline
Зарегистрирован: 26.11.2012

У экрана частота обновления супер, просто spi  у дуины медленный.

Immortal
Offline
Зарегистрирован: 28.12.2013

Определился с экраном - буду брать 2.8 Inch 240 x 320 ili9325 can connect any 16 bit data bus, подключать буду к ATmega128 через преобразователь уровней, шить через ISP ардуиной. С Stm32 дискавери решил повременить, я полный ноль в армах и Stm32.

Сложно будет переписать скетч под такой экран? (u8glib этот контроллер не поддерживает, придется перейти на UTFT)

 

dtvims
Offline
Зарегистрирован: 26.11.2012

Adafruit обычно имеет доп. библиотечки под конкретные моники, а если нет, то легко самому набрасать, библиотека очень простая. U8glib достаточно сложная в добавлении новых дисплеев, но тоже можно погуглить и возможно найти код и для нужного дисплея.

dtvims
Offline
Зарегистрирован: 26.11.2012

pooller пишет:

а на такой дисплей 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. Если все-равно памяти мало, то можно увеличивать ширину линий и размеры шрифтов, благо места навалом.

На картинке наводка 50hz