Good afternoon chaps i have been working from a design from you tube that uses a pc to read out coordinates but i wish to use an Arduino display with buttons to both zero the readout i.e. calibrate datum 0 then read out from that point in 3d space is it a case of using the original code and adding in the display or totally new code ?
attached is the one i am using currently and I'm using processing to display the data
i have 3 high resolution rotary encoders and a i2c 16x2 lcd shield
each arm will be about 500mm each I'm also hoping to ad a Safire ball to the end
digitizer_3d_3.ino (2.79 KB)
centoproject:
is it a case of using the original code and adding in the display or totally new code ?
It looks like the original code will work for generating the coordinates. You just have to add code for setting a new origin point and displaying the coordinates on the LCD instead of sending them to Serial.
sounds good can you help me with this if thats okey new to the Arduino community 
OK. Write a function that displays coordinates on the LCD. I'm sure your LCD library came with examples that will help.
looking through it all now i have know idea where i would begin apologies for being amateur with code
#define SET(x,y) (x |=(1<<y)) //-Bit set/clear macros
#define CLR(x,y) (x &= (~(1<<y))) // |
#define CHK(x,y) (x & (1<<y)) // |
#define TOG(x,y) (x^=(1<<y)) //-+
//**************************************************************************
// Hardware connections:
//**************************************************************************
//PORTD.7 (Arduino pin 7) Encoder 3 I Channel
//PORTD.6 (Arduino pin 6) Encoder 3 Q Channel
//PORTB.0 (Arduino pin 8) Encoder 0 I channel
//PORTB.1 (Arduino pin 9) Encoder 0 Q channel
//PORTB.2 (Arduino pin 10) Encoder 1 I channel
//PORTB.3 (Arduino pin 11) Encoder 1 Q channel
//PORTB.4 (Arduino pin 12) Encoder 2 I channel
//PORTB.5 (Arduino pin 13) Encoder 2 Q channel
volatile int encref[4][4]=
{
// 0 1 2 3
{
0, 1,-1, 128 }
,//0
{
-1, 0, 128, 1 }
,//1
{
1, 128, 0,-1 }
,//2
{
128,-1, 1, 0 }// 3
};
void sendFloat(float f,unsigned t) {
byte * b = (byte *) &f;
Serial.write(t);
Serial.write(b[0]);
Serial.write(b[1]);
Serial.write(b[2]);
Serial.write(b[3]);
}
volatile long encoder[4]={
0,0,0,0}; //-Encoder value
volatile unsigned char encoder_state=0; //-State machine variables
volatile unsigned char encoder_input; //-+
volatile unsigned char DIV=0;
volatile unsigned char flag=0;
volatile int offset;
volatile unsigned int error=0;
SIGNAL(TIMER1_COMPA_vect)
{
SET(PORTC,0);
OCR1A+=800; //16MHz/800=20KHz.
// OCR1A+=1600; //16MHz/800=20KHz.
encoder_input=(PINB&0b00111111)|(PIND&0b11000000); //-Encoder state machine
offset=encref[(encoder_state &0x03)][(encoder_input &0x03)];// |
if(offset==128)
error++;
else
encoder[0]+=offset;
offset=encref[(encoder_state>>2)&0x03][(encoder_input>>2)&0x03];// |
if(offset==128)
error++;
else
encoder[1]-=offset;
offset=encref[(encoder_state>>4)&0x03][(encoder_input>>4)&0x03];// |
if(offset==128)
error++;
else
encoder[2]-=offset;
offset=encref[(encoder_state>>6)&0x03][(encoder_input>>6)&0x03];
if(offset==128)
error++;
else
encoder[3]-=offset;
encoder_state=encoder_input; //-+
if(DIV==0)
{
DIV=200;
flag=1;
}
else
DIV--;
CLR(PORTC,0);
}
double A;
double B;
double C;
void setup()
{
SET(DDRC,0);
encoder[0]=(45.0/360)*2400.0;//45deg
encoder[1]=(32.048/360.0)*2400.0;
encoder[2]=(-113.174/360.0)*2400.0;
TCCR1A=0x00; //-Timer 1 inerrupt
TCCR1B=0x01; // |
TCCR1C=0x00; // |
SET(TIMSK1,OCIE1A); // |
sei(); //-+
TCCR0A=0;
TCCR0B=0;
Serial.begin(19200);
DDRD=0b00000000;
DDRB=0b00000000;
PORTB=0b00111111;
PORTD=0b11000000;
}
#define ARM 176.777
#define H0 (80.782-1.2)
//#define ARM 1767.77
//#define H0 (807.82-1.2)
void loop()
{
if(flag)
{
double A=(double)encoder[1]*M_PI/1200.0;
double B=(double)encoder[2]*M_PI/1200.0;
double C=(double)encoder[0]*M_PI/1200.0;
double D=(double)encoder[3]*M_PI/1200.0;
double r=cos(A)*ARM+cos(A+B)*ARM;
double h=sin(A)*ARM+sin(A+B)*ARM+H0;
double y=r*cos(C)-125;
double x=r*sin(C)-125;
double z=h;
flag=0;
while(!flag)
asm("nop");
sendFloat(x,'x');
flag=0;
while(!flag)
asm("nop");
sendFloat(y,'y');
flag=0;
while(!flag)
asm("nop");
sendFloat(z,'z');
flag=0;
while(!flag)
asm("nop");
sendFloat(D,'a');
// sendFloat(error ,'a');
}
}
What would i add to this to get it to display onto the lcd i know the lcd needs including code and the be set as active but I'm lost after that
centoproject:
i know the lcd needs including code and the be set as active but I'm lost after that
So start by adding the parts you know how to do or can figure out how to do by looking at the examples that came with the LCD library. You might find that by the time you have looked at enough examples to figure out the setup you will also have seen enough to know how to display stuff.
Attached is my first try can you please tell me if I'm going into the right direction ?
First_try_lcd.ino (4.11 KB)
centoproject:
Attached is my first try can you please tell me if I'm going into the right direction ?
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
This declaration would generally be a GLOBAL variable, outside of any function. You have put it inside loop(). Look at the library examples again.
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
This will generally only be done once. You put it inside loop() which is repeated over and over. You should put it inside setup() where it only gets done once. Look at the library examples again.
After you make those two changes, does the sketch do what you want? If not, what does it do differently? I don't have your hardware so YOU have to be the one to test the sketch.
Appreciate the help i will persevere tonight
thanks
I have been making progress tackling errors as they come but these 2 won't go away ! am i getting somewhere ?
First_try_lcd.ino (4.23 KB)
centoproject:
I have been making progress tackling errors as they come but these 2 won't go away ! am i getting somewhere ?
You seem to have two setup() functions. You can't do that. You have to merge the two.
You also have the #include files twice. You shouldn't do that. Put the #includes at the top.
You seem to have some extra and missing brackets. There must be one close bracket for each open bracket. A function must start with a return type, name, argument list, and open bracket:
void setup () {
It now displays
but just x : -49.04 nothing on the second row and the value dose not change with rotation ?
having just plugged it into the pc and tested the processing app it would appear that the values have frozen on that to attached is my amended code
First_try_lcd.ino (4.12 KB)
I don't see any reason why the display doesn't show Y as well as X. Let's try it without all that encoder stuff. Do the X and Y values both show up?
#include <Wire.h>
#include <Adafruit_RGBLCDShield.h>
#include <Adafruit_MCP23017.h>
//**************************************************************************
// Hardware connections:
//**************************************************************************
volatile long encoder[4] = {0, 0, 0, 0}; //-Encoder value
#define ARM 176.777
#define H0 (80.782-1.2)
//#define ARM 1767.77
//#define H0 (807.82-1.2)
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
void setup() {
// Debugging output
Serial.begin(9600);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
double A = (double)encoder[1] * M_PI / 1200.0;
double B = (double)encoder[2] * M_PI / 1200.0;
double C = (double)encoder[0] * M_PI / 1200.0;
// double D = (double)encoder[3] * M_PI / 1200.0;
double r = cos(A) * ARM + cos(A + B) * ARM;
// double h = sin(A) * ARM + sin(A + B) * ARM + H0;
double y = r * cos(C) - 125;
double x = r * sin(C) - 125;
// double z = h;
lcd.setCursor(0, 0); // Sets the location at which subsequent text written to the LCD will be displayed
lcd.print("X:"); // Prints string "Distance" on the LCD
lcd.print(x); // Prints the distance value from the sensor
lcd.setCursor(5, 0);
lcd.print("Y:");
lcd.print(y);
}
void loop() {}
yes it now displays the x:-12y:228.55
i have had a fiddle and got all three axis displaying as follows
x-125.00y28.55
z79.58
still no values changing but getting there ?
centoproject:
i have had a fiddle and got all three axis displaying as follows
x-125.00y28.55
z79.58
still no values changing but getting there ?
Since I took out the shaft encoder reading it makes sense that the readings won't change. I think the very dangerous direct port manipulations were causing the problem. There must be a library somewhere for reading a quadrature encoder.
If you only had two encoders the External Interrupt pins (2 and 3) could be used but since you are using three encoders it might make more sense to use Pin Change Interrupts. Arduino Playground - HomePage
let me direct you to the website o got the original idea from so you can visualise the set up
and are the pins easy to relocate ? and i didn't think there were any pin conflicts ? i.e. they do not physically overlap on the arduino
as a side note the link above are using the same encoders as me
centoproject:
are the pins easy to relocate ? and i didn't think there were any pin conflicts ? i.e. they do not physically overlap on the arduino
What pins need to be relocated? The code you copied from hits every UNO pin from 0 to 13 and also hits A0. Using an encoder library is likely to be less invasive than the direct port manipulation you have now.