I have been working on a recent project to build an Arduino Oscilloscope interfaced with a 4X4 keypad membrane with Nokia 5110 LCD display.I have successful individual code fragments/portions which 1)Generate waves interfaced with the keyboard 2)Display the same on the Nokia LCD 5110
i am using the Arduino Due and the 1st part of my code generates waves on DAC1 with the code as follows:-
#include "Waveforms.h"
#include <Keypad.h>
#include <LiquidCrystal.h>
//Set the desired duty cycle in percentage
double dc,t,a,d;
long d_milli,d_micro,a_milli,a_micro,m,n;
int stage =0;
int sample_delay1;
LiquidCrystal lcd(A2, A3, A4, A5, A6, A7);
float sample_delay;
String num1,num2;
int wave1;
String wave_name;
double duty_cycle,k;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'.','0','#','D'}
};
byte rowPins[ROWS] = {23,25,27,29}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {31,33,35,37}; //connect to the column pinouts of the keypad
int i = 0;
int sample;
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
boolean in_setup = true;
void setup()
{
Serial.begin(9600);
analogWriteResolution(12); // set the analog output resolution to 12 bit (4096 levels)
analogReadResolution(12);
lcd.begin(20,4);
char key = customKeypad.getKey();
lcd.setCursor(0, 0);
lcd.print("choose wave: ");
lcd.setCursor(0, 1);
lcd.print("A=Sine");
lcd.setCursor(8, 1);
lcd.print("B=Triangular");
lcd.setCursor(0, 2);
lcd.print("C=Sawtooth");
lcd.setCursor(11, 2);
lcd.print("D=Square");
while( true)
{
char key = customKeypad.getKey();
if(stage == 0)
{
Serial.println("in stage 0");
if(key == 'A' )
{
wave1 = 0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Sine? ");
wave_name ="Sinusoidal";
Serial.println(wave_name);
}
else if(key == 'B')
{
wave1 = 1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Triangular?");
wave_name ="Triangular";
Serial.println(wave_name);
}
else if(key == 'C')
{
wave1 = 2;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Sawtooth? ");
wave_name ="Sawtooth";
Serial.println(wave_name);
}
else if(key == 'D')
{
wave1 = 3;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Square? ");
wave_name ="Square";
Serial.println(wave_name);
}
else if(key == '#')
{
stage++;
//lcd.clear();
lcd.setCursor(0,1);
lcd.print("Frequency=");
Serial.println("Frequency=");
}
}
else if(stage == 1)
{
if(key != NO_KEY &&(key=='1'||key=='2'||key=='3'||key=='4'||key=='5'||key=='6'||key=='7'||key=='8'||key=='9'||key=='0'))
{
num1 = num1 + key;
//int numLength = num1.length();
//to adjust one whitespace for operator
lcd.setCursor(10,1);
lcd.print(num1);
}
else if(key == '#')
{
k = num1.toInt();
Serial.print(k);
int sample_delay_int = 1000000/(k*120);
float sample_delay_float = 1000000/(k*120);
float difference= sample_delay_float-sample_delay_int;
sample_delay1 = sample_delay_int - 6;
if(difference > 0.5)
{
sample_delay1++;
}
Serial.println(sample_delay1);
lcd.clear();
lcd.print(wave_name);
lcd.setCursor(0,1);
lcd.print("Frequency=");
lcd.print(num1);
lcd.print(" Hz");
break;
}
}
}
}
void loop()
{
analogWrite(DAC1, waveformsTable[wave1][i] );
i++;
if(i == maxSamplesNum) // Reset the counter to repeat the wave
i = 0;
else
delayMicroseconds(sample_delay1);
}
Next, I input these waves from DAC1 into analog input A0 to display on the LCD with code as below:-
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <SPI.h>
#define DISPLAY_WIDTH 84
#define DISPLAY_HEIGHT 48
#define ARDUINO_PRECISION 1023.0
Adafruit_PCD8544 display = Adafruit_PCD8544(8,9,10,12,11);
//Analog Pins
int channelAI = A0; // probe
#define DELAY_POTENTIMETER //disabled it I don't have it connected
#ifdef DELAY_POTENTIMETER
int delayAI = A1; // delay potentiometer
#endif
float delayVariable = 0;
float scale = 0;
int xCounter = 0;
int yPosition = 0;
int readings[DISPLAY_WIDTH+1];
int counter = 0;
unsigned long drawtime = 0;
unsigned long lastdraw = 0;
int frames = 0;
void setup(void)
{
display.begin();
display.setContrast(30);// you might have a slightly different display so it might not be the optimal value for you
display.clearDisplay();
}
void loop()
{
#ifdef DELAY_POTENTIMETER
delayVariable = analogRead(delayAI);
delayVariable = (delayVariable/100);
#endif
scale = (float)(DISPLAY_HEIGHT-1)/ARDUINO_PRECISION;
//record readings
for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
{
yPosition = analogRead(channelAI);
readings[xCounter] = (yPosition*scale);
#ifdef DELAY_POTENTIMETER
delay (delayVariable);
#endif
}
display.clearDisplay();
//Draw Voltage Ref Lines
display.drawLine( 10, 0, 10, DISPLAY_HEIGHT-1, BLACK);
display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), BLACK);
display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), BLACK);
display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), BLACK);
display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), BLACK);
//display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), BLACK);
//Draw Voltage Ref Numbers
display.setCursor(0,((DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale))-3);
display.print((int)(5.0*0.2));
display.setCursor(0,((DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale))-3);
display.print((int)(5.0*0.4));
display.setCursor(0,((DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale))-3);
display.print((int)(5.0*0.6));
display.setCursor(0,((DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale))-3);
display.print((int)(5.0*0.8));
for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
{
display.drawPixel(xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
if(xCounter>1){
display.drawLine(xCounter-1, (DISPLAY_HEIGHT-1)-readings[xCounter-1], xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
}
}
//Draw FPS
display.setCursor((DISPLAY_WIDTH-1)-11,0);
display.print(frames);
//Draw Voltage
display.setCursor(((DISPLAY_WIDTH-1)/2),0);
display.print(analogRead(channelAI)/ARDUINO_PRECISION*5.0);
display.display();
//Calculate FPS
drawtime = micros();
frames=1000000/*a second*//(drawtime-lastdraw);
lastdraw = drawtime;
}
Now the problem arises when i try doing the 2 things on d same arduino due board. I got perfect results when i used arduino due and arduino uno simultaneously but have not been able to generate waves on the LCD using the same board. Is it possible to do the same. Can some1 help me incorporate the 2 programs into 1 ..Thanxx
I tried playing around with my setup() and loop() and have reached a point where my program does everything ,ie takes keypad input ,displays options on the LCD ,takes in freq and generates a splashscreen but the only thing i'm missing out on is d wave display on the LCD (I'm able to see the selected wave on the DSO) ..So i guess i'm pretty close, and the edited code is as follows:-
#include "waveforms.h"
#include <Keypad.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <gfxfont.h>
#include <Adafruit_PCD8544.h>
//Set the desired duty cycle in percentage
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 10, 12, 11);
double dc,t,a,d;
long d_milli,d_micro,a_milli,a_micro,m,n;
int stage =0;
int sample_delay1;
float sample_delay;
String num1,num2;
int wave1;
String wave_name;
double duty_cycle,k,Z;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'.','0','#','D'}
};
byte rowPins[ROWS] = {23,25,27,29}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {31,33,35,37}; //connect to the column pinouts of the keypad
int i = 0;
int t_sample;
#define DISPLAY_WIDTH 84
#define DISPLAY_HEIGHT 48
#define ARDUINO_PRECISION 1023.0
//Adafruit_PCD8544 display = Adafruit_PCD8544(8,9,10,12,11);
//Analog Pins
int channelAI=A0;
#define DELAY_POTENTIMETER //disabled it I don't have it connected
#ifdef DELAY_POTENTIMETER
int delayAI = A1; // delay potentiometer
#endif
float delayVariable = 0;
float scale = 0;
int xCounter = 0;
int yPosition = 0;
int readings[DISPLAY_WIDTH+1];
int counter = 0;
unsigned long drawtime = 0;
unsigned long lastdraw = 0;
int frames = 0;
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
boolean in_setup = true;
void setup()
{
Serial.begin(9600);
analogWriteResolution(12); // set the analog output resolution to 12 bit (4096 levels)
analogReadResolution(12);
display.begin(20,4);
char key = customKeypad.getKey();
display.begin();
display.display();
display.setContrast(40);// you might have a slightly different display so it might not be the optimal value for you
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0, 0);
display.print("choose wave: ");
display.display();
display.setCursor(1, 8);
display.print("A=Sine");
display.display();
display.setCursor(1,16);
display.print("B=Triangular");
display.display();
display.setCursor(1,24);
display.print("C=Sawtooth");
display.display();
display.setCursor(1,32);
display.print("D=Square");
display.display();
while( true)
{
char key = customKeypad.getKey();
if(stage == 0)
{
Serial.println("in stage 0");
if(key == 'A' )
{
wave1 = 0;
display.clearDisplay();
display.setCursor(0,0);
display.print(" Sine? ");
display.display();
wave_name ="Sinusoidal";
Serial.println(wave_name);
}
else if(key == 'B')
{
wave1 = 1;
display.clearDisplay();
display.setCursor(0,0);
display.print("Triangular?");
display.display();
wave_name ="Triangular";
Serial.println(wave_name);
}
else if(key == 'C')
{
wave1 = 2;
display.clearDisplay();
display.setCursor(0,0);
display.print("Sawtooth? ");
display.display();
wave_name ="Sawtooth";
Serial.println(wave_name);
}
else if(key == 'D')
{
wave1 = 3;
display.clearDisplay();
display.setCursor(0,0);
display.print("Square? ");
display.display();
wave_name ="Square";
Serial.println(wave_name);
}
else if(key == '#')
{
stage++;
display.clearDisplay();
display.setCursor(20, 8);
display.println("Freq=");
display.display();
Serial.println("Frequency=");
}
}
else if(stage == 1)
{
if(key != NO_KEY &&(key=='1'||key=='2'||key=='3'||key=='4'||key=='5'||key=='6'||key=='7'||key=='8'||key=='9'||key=='0'))
{
num1 = num1 + key;
//int numLength = num1.length();
//to adjust one whitespace for operator
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(48, 9);
display.print(num1);
display.display();
}
else if(key == '#')
{
stage++;
k = num1.toInt();
Serial.print(k);
display.setTextSize(1);
display.setTextColor(BLACK);
display.display();
display.setCursor(10, 1);
int sample_delay_int = 1000000 / (k * 120);
float sample_delay_float = 1000000 / (k * 120);
float difference = sample_delay_float - sample_delay_int;
sample_delay1 = sample_delay_int - 6;
if (difference > 0.5)
{
sample_delay1++;
}
display.display();
Serial.println(sample_delay1);
display.clearDisplay();
display.print(wave_name);
display.setCursor(1, 8);
display.println("Freq=");
display.print(num1);
display.println(" Hz");
break;
}
}
}
//record readings
for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
{
yPosition = analogRead(A0);
readings[xCounter] = (yPosition*scale);
#ifdef DELAY_POTENTIMETER
delay (delayVariable);
#endif
}
display.clearDisplay();
#ifdef DELAY_POTENTIMETER
delayVariable = analogRead(delayAI);
display.display();
delayVariable = (delayVariable/100);
#endif
scale = (float)(DISPLAY_HEIGHT-1)/ARDUINO_PRECISION;
//Draw Voltage Ref Lines
display.drawLine( 10, 0, 10, DISPLAY_HEIGHT-1, BLACK);
display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), BLACK);
display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), BLACK);
display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), BLACK);
display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), BLACK);
//display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), BLACK);
//Draw Voltage Ref Numbers
display.setCursor(0,((DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale))-3);
display.print((int)(5.0*0.2));
display.setCursor(0,((DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale))-3);
display.print((int)(5.0*0.4));
display.setCursor(0,((DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale))-3);
display.print((int)(5.0*0.6));
display.setCursor(0,((DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale))-3);
display.print((int)(5.0*0.8));
for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
{
display.drawPixel(xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
if(xCounter>1){
display.drawLine(xCounter-1, (DISPLAY_HEIGHT-1)-readings[xCounter-1], xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
}
}
//Draw FPS
display.setCursor((DISPLAY_WIDTH-1)-11,0);
display.print(frames);
//Draw Voltage
display.setCursor(((DISPLAY_WIDTH-1)/2),0);
display.print(analogRead(A0)/ARDUINO_PRECISION*5.0);
display.display();
//Calculate FPS
drawtime = micros();
frames=1000000/(drawtime-lastdraw);
lastdraw = drawtime;
display.display();
}
void loop()
{
analogWrite(DAC1, waveformsTable[wave1][i] );
i++;
if(i == maxSamplesNum) // Reset the counter to repeat the wave
i = 0;
else
delayMicroseconds(sample_delay1);
analogWrite(DAC0, waveformsTable[wave1][i] );
i++;
if(i == maxSamplesNum) // Reset the counter to repeat the wave
i = 0;
else
delayMicroseconds(sample_delay1);
}
Can some1 possibly tinker around with this ..It'll b a huge help!!