Go Down

Topic: My Oscillocope (Read 1 time) previous topic - next topic

Metalfan1185

Feb 13, 2010, 12:39 am Last Edit: Feb 13, 2010, 12:41 am by Metalfan1185 Reason: 1
I made a O scope kind of project that plots a line on a GLCD screen based on an analog Voltage input.  Its very simple.

The only issue is that where the actual voltage (numeric) is displayed to the screen, It will only print the whole integer as a Voltage (2, 3, 4, ) I want to add a decimal, such as 3.45    2.76    4.45

can someone help me? i appreciate it...

Ill post a Video on youtube and link it here after i make that final change.


Code: [Select]
#include <ks0108.h>
#include "Arial14.h"         // proportional font
#include "SystemFont5x7.h"   // system font
#include "ArduinoIcon.h"     // bitmap

unsigned long startMillis;
unsigned int loops = 0;
unsigned int iter = 0;
int Benchcount = 0;
int InputPin = 0;
int PlotVoltage = 0;
int VoltageValue = 0;
 int d = 1;
 int p = 0;
 int x = 0; //x graph coordinate
 int y = 0; //y graph coordinate
 int a = 0; //old x graph coordinate
 int b = 0; //old y graph coordinate
 int e = 0;
 int f = 0;


void setup(){
 GLCD.Init(NON_INVERTED);   // initialise the library, non inverted writes pixels onto a clear screen
 GLCD.ClearScreen();  
 GLCD.SelectFont(System5x7); // switch to fixed width system font

}


void  loop(){   // run over and over again
 byte r;
 char str[16];
   
   
 //Dotted Line to Center Plot Graph Area Horizontally
 d = 0;
 for (int i=0; i <= 64; i++){ //dotted graph line
 GLCD.SetDot(d, 32, BLACK);
 d = d + 2;
 }

 static float p;
 static float x;

 PlotVoltage = analogRead(InputPin);
 VoltageValue = (PlotVoltage * .004882813);
//Draw Rectangles on top and bottom corners to display RAW Data from Analog Reading
 GLCD.DrawRect(98, 0, 29, 10, BLACK);  //Uncomment these lines for for Top Corner *
 GLCD.FillRect(99, 1, 27, 8, WHITE); //                                           *
 GLCD.GotoXY(102,02); //                                                          *
 GLCD.PrintNumber(PlotVoltage);                 //                                *
 GLCD.DrawRect(98, 53, 29, 10, BLACK);  //# Uncomment these 4 lines for bottom Corner
 GLCD.FillRect(99, 54, 27, 8, WHITE);   //#
 GLCD.GotoXY(102,63);  //                 #
 GLCD.PrintNumber(VoltageValue); //        #


 
 if (PlotVoltage > p){ //print peak graph value
// GLCD.FillRect(97, 05, 29, 10, WHITE);
// GLCD.GotoXY(98,119);
// GLCD.PrintNumber(PlotVoltage);
 p= PlotVoltage;
 }
 
//Add Scaling...Bottom most line (y=63 is 0V, y=1 is 5V)
GLCD.DrawLine(0, 0, 0, 63, BLACK);  //Line for Scaleing Tally Marks
GLCD.DrawLine(0, 0, 4, 0, BLACK); //Topmost Mark
GLCD.DrawLine(0, 8, 2, 8, BLACK);
GLCD.DrawLine(0, 16, 4, 16, BLACK);
GLCD.DrawLine(0, 24, 2, 24, BLACK);
GLCD.DrawLine(0, 32, 4, 32, BLACK); //Center Mark
GLCD.DrawLine(0, 40, 2, 40, BLACK);
GLCD.DrawLine(0 ,48, 4, 48, BLACK);
GLCD.DrawLine(0, 56, 2, 56, BLACK);
GLCD.DrawLine(0, 63, 4, 63, BLACK);//BottomMost Mark

 
 int y = 63 - (PlotVoltage /16);  //y coordinate of graph curve  ***Careful when adjusting the '/16' part. Y should be where you want the lowest reading displayed and
 if(b == 0){                       //                            the divisor number adjusts the scaleing (sensitivity) based on where that line is...
 b = y;                             //                           The lower the number, the higher sensitivity/max reading is plotted on graph
 }
 
 GLCD.DrawLine(a,b,x,y, BLACK);
 x++; // add 1 to old x coordinate for line drawing in right direction
 
 if (x == 128){ //clean screan when graph cycle will start again from left
 GLCD.ClearScreen();
 x = 0; //x coordinate to start graph from left again

 }
   a = x; //old x coordinate to use for drawing line to new x coordinate
 b = y; //old y coordinate to use for drawing line to new y coordinate

}

// GLCD.Init(invert) initialize the library for normal or inverted drawing. If invert is false,
//  drawing sets pixels, if true pixels are cleared when drawn (see also SetInverted method)
// GLCD.GotoXY(x,y) locate the graphic cursor at positions x and y, 0,0 is upper left corner
// GLCD.ClearScreen() clear the LCD screen

          // Graphic Drawing Functions (color WHITE clears pixels, BLACK sets pixels)
// GLCD.DrawCircle(x, y, radius, color) draw circle with center at x,y
// GLCD.DrawLine(x1,y1,x2,y2,color) draw line from x1,y1 to x2,y2
// GLCD.DrawVertLine(x, y, length, color) draw vertical line
// GLCD.DrawHoriLine(x, y, length, color) draw horizontal line  
// GLCD.DrawRect(x, y, width, height, color) draw rectangle
// GLCD.DrawRoundRect(x, y, width, height, radius, color) as above with rounded edges
// GLCD.FillRect(x, y, width, height, color) draw filled rectangle
// GLCD.InvertRect(x, y, width, height) invert pixels within given rectangle
// GLCD.SetInverted(invert) set drawing mode to inverted
// GLCD.SetDot(x, y, color); draw a dot in the given color at the given location
// GLCD.DrawBitmap(bitmap, x, y, color); draw the bitmap at the given x,y position

         // Font Functions
// GLCD.SelectFont(font, color ) select font, defaults color to black if not specified
// GLCD.PutChar(character) print given character to screen at current cursor location
// GLCD.Puts(string) print given string to screen at current cursor location
// GLCD.Puts_P(string) print string from program memory to screen at current cursor location
// GLCD.PrintNumber(number) print the decimal value of the given number at current cursor location
// GLCD.CursorTo(x, y); // 0 based coordinates for fixed width fonts (i.e. the supplied system font)


This is based on a Code that I found online, But I subject it to Heavy modifications  8-)

dpharris

Instead of your:
Code: [Select]

GLCD.PrintNumber(VoltageValue);


Perhaps:  

Code: [Select]

int whole=VoltageValue/100;
int fraction=VoltageValue-whole*100;
GLCD.PrintNumber(whole);
GLCD.PrintPutChar('.');
GLCD.PrintNumber(fraction);


David
Dr. David Harris
OpenLCB Dev Team

Metalfan1185

#2
Feb 13, 2010, 02:38 am Last Edit: Feb 13, 2010, 02:39 am by Metalfan1185 Reason: 1
Thank You,

It's very close, but what I get is

.3  (Where 3 is the whole Volts)

You gave me an idea though, so im still messin with it.

Code: [Select]
//Draw Rectangles on top and bottom corners to display RAW Data from Analog Reading
 GLCD.DrawRect(98, 0, 29, 10, BLACK);  //Uncomment these lines for for Top Corner *
 GLCD.FillRect(99, 1, 27, 8, WHITE); //                                           *
 GLCD.GotoXY(102,02); //                                                          *
//  GLCD.PrintNumber(VoltageValue);                 //                                *
 int whole=VoltageValue/100;
 int fraction = VoltageValue - whole * 100;
 GLCD.PrintNumber(whole);
 GLCD.PutChar('.');
 GLCD.PrintNumber(fraction);

Metalfan1185

nah, I can't fgure it out...

is it a possibility that maybe there is a need to manipulate the Raw analog reading before it is converted to a voltage (via * .00488blah blah blah)

I know this goes between 0 and 1023, but the thought of getting a fraction voltage in decimal form seems very difficult to me.

dpharris

If you want two decimal points then keep you VoltageValue as V*100, so 0V = 0, 0.5V = 50, 5V=500.  You will have to do a conversion between the A/D value to get the right value.  Then to display:
Code: [Select]

int whole=VoltageValue/100;
int fraction=VoltageValue-whole*100;
GLCD.PrintNumber(whole);
GLCD.PrintPutChar('.');
GLCD.PrintNumber(fraction);


David
Dr. David Harris
OpenLCB Dev Team

Metalfan1185

#5
Feb 13, 2010, 04:18 am Last Edit: Feb 13, 2010, 04:34 am by Metalfan1185 Reason: 1
hmmm...heres my thoughts...


So i need something that can take the numeric value from an analog pin and convert it to a decimal, (integer)

If you divide 5 by 1024 you get .004882813
sooooooo

to move from 0V to .01V, you would increase ADC value by lets see, 2 steps would give you 0.009765626V...

I wonder if that little bit will make a big difference as the numbers increase.

if we try this, .01V = (approx) 2 steps.
so 4 steps would be .02
40 steps would be .20
400 steps would be 2V

but actual calc:

.004882813 * 400 = 1.95V...this is super close, lets go higher



800 steps should be 4V
---this would double the loss, so at 800 steps, instead of 4V it would be 3.90V


1000Steps would ideally be 5V, so the remaining 24 would leave an error margin of (24 * .004882813) or 0.117187512V away from target at full scale.



.01V = (1 * 2.04799979) in ADC steps
.02V = 4.09599958  (= 2 * 2.04799979)
.03V = 6.14399937
.30V = 61.4399937
3.0V = 614.399937


So if I were to measure  3.33V, that is (333 * 2.04799979) = 681.98393007

in reverse, this is

681 / 2.04799979 = 332.519565346 (or 3.325V)


Metalfan1185

So if I were to measure  3.33V, that is (333 * 2.04799979) = 681.98393007

in reverse, this is

681 / 2.04799979 = 332.519565346 (or 3.325V)


lets try 1024

1024 / 2.04799979 = 500.00005127   :D  i think we have a winner


So i need to take the RAW ADC value and divide it by 2.04799979 to get a value that is correct numerically, but not with the decimal place...

but your code shoud fix that...i think...

correct?

Metalfan1185

Made this edit and works like a charm...

Code: [Select]
 VoltageValue = (PlotVoltage / 2.04799979);
 int whole=VoltageValue/100;
 int fraction = VoltageValue - whole * 100;
 GLCD.PrintNumber(whole);
 GLCD.PutChar('.');
 GLCD.PrintNumber(fraction);


Thank You for your help...I just had to talk to myself for a little while to wrap my head around what you were trying to explain to me  ;D

Go Up