Go Down

### Topic: Improved Esplora TFT Horizon (Read 10905 times)previous topic - next topic

#### kor1989 ##### Sep 06, 2013, 12:39 amLast Edit: Sep 06, 2013, 11:44 am by kor1989 Reason: 1
Hi, I have tried to improve the Esplora TFT Horizon making it a little more sensitive to high inclination and adding also a line to represent vertical inclination. The angles are also printed to the serial port.

Quote

/*
Created 25 August 2013 by Corrado Possieri
*/

// first of all we need to include the libraries
#include <Esplora.h>
#include <TFT.h>            // Arduino LCD library
#include <SPI.h>

// some variables that the Esplora need to work correctly
// we have to define the center of the screen
const float X0 = EsploraTFT.width()/2.0;
const float Y0 = EsploraTFT.height()/2.0;

// and the limit values for the accelerometer
// good values not considering the acceleration impressed
// to Esplora are those (you can try also the values after comment)
int xAccMin = -180; // -150;
int xAccMax = 180; //170;
int yAccMin = -180; //-147;
int yAccMax = 180; //190;
int zAccMin = -180; //-150;
int zAccMax = 180; //170;

// we need also to save in a global variable the last angle
float lastTanAngle;
float lastZIncl;

// this function will be executed once at the beginning
void setup() {
// we need to initialize the display
EsploraTFT.begin();

// and to select the color of the background
EsploraTFT.background(0,0,0); // black for an higher contrast

// begin the serial comunication
Serial.begin(9600);
}

// this will run over and over
void loop() {
// we need to read the Accelerometer values...

// ...and to remap them in a fixed range scale
const int scale = 1000;
float xIncl = map(xAxis, xAccMin, xAccMax, -scale, scale);
float yIncl = map(yAxis, yAccMin, yAccMax, -scale, scale);
float zIncl = map(zAxis, zAccMin, zAccMax, scale, -scale);

// horizontal inclination
float horizontalAngle = atan2(xIncl, yIncl);
// vertical inclination
float verticalInclination = atan2(yIncl, -zIncl);

// print these values to the serial port
Serial.print("horizontal angle: ");
Serial.println(horizontalAngle/PI*180);
Serial.print("verical angle: ");
Serial.println(verticalInclination/PI*180);
Serial.println();

// no we can graph the values in the tft screen
// this value represent the offset of the line
// which represent the ground
float zOffset = map(zAxis, zAccMin, zAccMax, Y0, -Y0);
// this represent the inclination respect the horizon
float tanAngle = xIncl/yIncl;

// first of all we have to delete the previous lines
// drawing black lines over them
// horizontal inclination
EsploraTFT.stroke(0,0,0); // we draw black over the previous lines
EsploraTFT.line(0, -X0*lastTanAngle+Y0, 2*X0, X0*lastTanAngle+Y0);
// vertical inclination
EsploraTFT.line(0, -X0*lastTanAngle+lastZIncl+Y0,
2*X0, X0*lastTanAngle+lastZIncl+Y0);

// now we can write the new lines
// one for horizontal inclination
EsploraTFT.stroke(0,255,0); // this line would be green
EsploraTFT.line(0, -X0*tanAngle+Y0, 2*X0, X0*tanAngle+Y0);
// this line would be red
// and one for vertical
EsploraTFT.stroke(255,0,0);
EsploraTFT.line(0, -X0*tanAngle+zOffset+Y0, 2*X0, X0*tanAngle+zOffset+Y0);

// we will save the values for the next loop iteration
lastTanAngle = tanAngle;
lastZIncl = zOffset;

// a little delay for stability
delay(100);
}

I hope this will help.
Happy sketching

#### TheKitty #1
Excellent work!

#### kor1989 #2
Thanks a lot!

#### kor1989 #3
##### Sep 07, 2013, 05:17 pm
Hi, I have tried to improve a little my code adding a Processing Sketch that permits also to understand what's going on for users which does not have the LCD

The code for Arduino has little changes that permits to send a float through serial port using an union

Quote

/*
Created 25 August 2013 by Corrado Possieri
*/

// first of all we need to include the libraries
#include <Esplora.h>
#include <TFT.h>            // Arduino LCD library
#include <SPI.h>

// some variables that the Esplora need to work correctly
// we have to define the center of the screen
const float X0 = EsploraTFT.width()/2.0;
const float Y0 = EsploraTFT.height()/2.0;

// and the limit values for the accelerometer
// good values not considering the acceleration impressed
// to Esplora are those (you can try also the values after comment)
int xAccMin = -180; // -150;
int xAccMax = 180; //170;
int yAccMin = -180; //-147;
int yAccMax = 180; //190;
int zAccMin = -180; //-150;
int zAccMax = 180; //170;

// we need also to save in a global variable the last angle
float lastTanAngle;
float lastZIncl;

// declare an union to convert from float to an array of bytes
// to send them to the serial port
union FLOAT2BYTE {
float myFloat;
byte byte_s;
} S_FLOAT;

// this function will be executed once at the beginning
void setup() {
// we need to initialize the display
EsploraTFT.begin();

// and to select the color of the background
EsploraTFT.background(0,0,0); // black for an higher contrast

// begin the serial comunication
Serial.begin(9600);
// send a byte to establish contact until receiver responds
establishContact();
}

// this will run over and over
void loop() {
// we need to read the Accelerometer values...

// ...and to remap them in a fixed range scale
const int scale = 1000;
float xIncl = map(xAxis, xAccMin, xAccMax, -scale, scale);
float yIncl = map(yAxis, yAccMin, yAccMax, -scale, scale);
float zIncl = map(zAxis, zAccMin, zAccMax, scale, -scale);

// horizontal inclination
float horizontalAngle = atan2(xIncl, yIncl);
// vertical inclination
float verticalInclination = atan2(yIncl, -zIncl);

// print these values to the serial port
sendFloat(horizontalAngle);
sendFloat(verticalInclination);

// no we can graph the values in the tft screen
// this value represent the offset of the line
// which represent the ground
float zOffset = map(zAxis, zAccMin, zAccMax, Y0, -Y0);
// this represent the inclination respect the horizon
float tanAngle = xIncl/yIncl;

// first of all we have to delete the previous lines
// drawing black lines over them
// horizontal inclination
EsploraTFT.stroke(0,0,0); // we draw black over the previous lines
EsploraTFT.line(0, -X0*lastTanAngle+Y0, 2*X0, X0*lastTanAngle+Y0);
// vertical inclination
EsploraTFT.line(0, -X0*lastTanAngle+lastZIncl+Y0,
2*X0, X0*lastTanAngle+lastZIncl+Y0);

// now we can write the new lines
// one for horizontal inclination
EsploraTFT.stroke(0,255,0); // this line would be green
EsploraTFT.line(0, -X0*tanAngle+Y0, 2*X0, X0*tanAngle+Y0);
// this line would be red
// and one for vertical
EsploraTFT.stroke(255,0,0);
EsploraTFT.line(0, -X0*tanAngle+zOffset+Y0, 2*X0, X0*tanAngle+zOffset+Y0);

// we will save the values for the next loop iteration
lastTanAngle = tanAngle;
lastZIncl = zOffset;

// a little delay for stability
delay(100);
}

void sendFloat(float floatToSend) {
// we can send a float to serial port
S_FLOAT.myFloat = floatToSend;
for(int ii = 0; ii < 4; ii++) {
// we have to write bytes on serial port
Serial.write(S_FLOAT.byte_s[ii]);
}
}

void establishContact() {
// save the start time
unsigned long startTime = millis();
// until we have a response from the pc
while (Serial.available() <= 0) {
Serial.print('A');   // send a capital A
// if we are waiting from more than 10 seconds
if(millis() - startTime > 10000) {
// we will not comunicate with computer
break;
}
delay(300);
}
}

#### kor1989 #4
##### Sep 07, 2013, 05:19 pmLast Edit: Sep 07, 2013, 05:26 pm by kor1989 Reason: 1
And this is the Processing code that permits the communication with Arduino Esplora.
Quote

/*
created by Corrado Possieri on 7/09/2013
*/

// import the serial library of processing
// for serial comunication
import processing.serial.*;

// rotation angles (global variables because they are updated in
// the serialEvent function
float rotateY = 0;
float rotateX= PI/3;

// global variables for serial comunication
boolean firstContact = false;
int[] serialInArray = new int;
int serialCount = 0; // number of bytes received

// declare the serial port
Serial myPort;

void setup() {
// decide the size of the window
size(800,650,OPENGL);

// list of serial ports avaliable
println("Serial ports available");
println(Serial.list());
// we have to choose the Arduino one
String portName = Serial.list();
// connect to this serial port
myPort = new Serial(this, portName, 9600);
}

void draw () {
// selection of the background
background(150, 255, 150);
// iinsert a white light
directionalLight(255, 255, 255, 0, 1, -1);
// we don't want any line
noStroke();

// go a little back to have a better view
translate(400,325,-150);
// rotations comunicated by Arduino
rotateX(rotateX);
rotateY(rotateY);

// draw the floor
pushMatrix();
translate(0,-318,0);
// draw a little reference system
sistRif(50);
// select the color of the floor
fill(31,8,250);
// save actual reference system
pushMatrix();
// draw the floor like a box
translate(0,0,-50);
box(5000,5000,100);
popMatrix();
// draw some lines on the floor to have a better view
stroke(0);
for(int kkk=-2500; kkk<=2500; kkk=kkk+100) {
line(kkk, -2500, 0, kkk, 2500, 0);
line(-2500, kkk, 0, 2500, kkk, 0);
}
popMatrix();
}

void sistRif (float length)
{
// draw a reference system to better understand
// what you have done
strokeWeight(3);
stroke(255,0,0);
line(0,0,0,length,0,0); // x
stroke(0,255,0);
line(0,0,0,0,length,0); // y
stroke(0,0,255);
line(0,0,0,0,0,length); // z
noStroke();
}

// when datas are available on the serial port
void serialEvent(Serial myPort) {
// if this is the first byte clear the serial port, we have had
// the first contact, and give this information to Arduino
if (firstContact == false) {
if (inByte == 'A') {
myPort.clear();  // clear the serial port
firstContact = true;  // connection done
myPort.write('A'); // wait
}
else {
serialInArray[serialCount] = inByte;
serialCount++;
println(serialInArray);
println();

if (serialCount > 7) {
// decode received bytes to obtain 2 floats
int asInt1 = (serialInArray & 0xFF)
| ((serialInArray & 0xFF) << 8)
| ((serialInArray & 0xFF) << 16)
| ((serialInArray & 0xFF) << 24);
rotateY = Float.intBitsToFloat(asInt1);
println(rotateY);

int asInt2 = (serialInArray & 0xFF)
| ((serialInArray & 0xFF) << 8)
| ((serialInArray & 0xFF) << 16)
| ((serialInArray & 0xFF) << 24);
rotateX = Float.intBitsToFloat(asInt2);
println(rotateX);

// Reset serialCount
serialCount = 0;
}
}
}

Excuse me but i had to divide the message into tho halves because it was too long.
In the previous message i also attached two screenshot of the Processing code.
Always hoping this will help
Happy sketching

Go Up
{"ft_lang_label":"__label__en","ft_lang_prob":0.5983538,"math_prob":0.95396835,"size":3304,"snap":"2020-34-2020-40","text_gpt3_token_len":990,"char_repetition_ratio":0.13424243,"word_repetition_ratio":0.012048192,"special_character_ratio":0.34079903,"punctuation_ratio":0.20352565,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.96306115,"pos_list":[0,1,2,3,4,5,6,7,8,9,10],"im_url_duplicate_count":[null,null,null,null,null,null,null,null,null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2020-09-21T15:34:00Z\",\"WARC-Record-ID\":\"<urn:uuid:33925bf1-cc36-4b6a-9bdc-418c9c615cd2>\",\"Content-Length\":\"63716\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:813ec0e6-9b2a-47e7-bf65-42fa3feb033c>\",\"WARC-Concurrent-To\":\"<urn:uuid:ffede866-4059-458e-a60f-9ad8d99b4982>\",\"WARC-IP-Address\":\"104.22.48.75\",\"WARC-Target-URI\":\"https://forum.arduino.cc/index.php?topic=142511.0;prev_next=prev\",\"WARC-Payload-Digest\":\"sha1:4FCT47W4RND3CZFSJ5LT526KZXCU6LVM\",\"WARC-Block-Digest\":\"sha1:WBZQAACC7YO5OH55KFLRJHM7DWSPJGM6\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2020/CC-MAIN-2020-40/CC-MAIN-2020-40_segments_1600400201826.20_warc_CC-MAIN-20200921143722-20200921173722-00103.warc.gz\"}"}