Hi, I am currently doing my fyp project that requires me to plot a line graph on my TFT screen, which has an ILI9341 controller drive. I am using the 6-axis IMU sensor and Force-sensitive resistive sensor, and I need to plot a line graph based on the input data from these sensors.
TFT screen: 2.8 TFT Touch Shield for Arduino with Resistive Touch Screen : ID 1651 : $34.95 : Adafruit Industries, Unique & fun DIY electronics and kits
IMU: https://www.makersupplies.sg/products/mpu-6050-six-axis-unsoldered?variant=17216531595310¤cy=SGD&utm_campaign=gs-2019-09-08&utm_source=google&utm_medium=smart_campaign&gclid=Cj0KCQiAkKnyBRDwARIsALtxe7ixvjAhjgECytEEYCllCEjaHmfApNpAfjtmBiWY3eGlFcWBbtNQpx8aAtsVEALw_wcB
Force-sensitive resistive sensor: https://www.sgbotic.com/index.php?dispatch=products.view&product_id=1085
Currently, I have successfully programmed both IMU and force-sensitive resistive sensors, and I'm stuck at plotting the graph. (I have attached the code for IMU + force-sensitive resistive sensor)
#include "Wire.h"
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#define TFT_DC 9
#define TFT_CS 10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
const int MPU = 0x68; // MPU6050 I2C address
float GyroX, GyroY, GyroZ;
float GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;
int Resultant;
int fsrPin = 8; // the FSR and 10K pulldown are connected to a0
int fsrReading; // the analog reading from the FSR resistor divider
int fsrVoltage; // the analog reading converted to voltage
unsigned long fsrResistance; // The voltage converted to resistance, can be very big so make "long"
unsigned long fsrConductance;
long fsrForce; // Finally, the resistance converted to force
void setup() {
Serial.begin(9600);
tft.begin();
tft.fillScreen(ILI9341_BLACK);
tft.setRotation(4);
//IMU
Wire.begin(); // Initialize comunication
Wire.beginTransmission(MPU); // Start communication with MPU6050 // MPU=0x68
Wire.write(0x6B); // Talk to the register 6B
Wire.write(0x00); // Make reset - place a 0 into the 6B register
Wire.endTransmission(true); //end the transmission
//calculate_IMU_error();
pinMode(40, OUTPUT); //LED
tft.setTextColor(ILI9341_WHITE,ILI9341_BLACK); tft.setTextSize(1);
tft.setCursor(0,5);
tft.print("Angular Velocity (deg/sec): ");
tft.setTextColor(ILI9341_WHITE,ILI9341_BLACK); tft.setTextSize(1);
tft.setCursor(0,18);
tft.print("Force in Forearm(N): ");
delay(20);
}
void loop() {
digitalWrite(40, HIGH);
// === Read gyroscope data === //
previousTime = currentTime; // Previous time is stored before the actual time read
currentTime = millis(); // Current time actual time read
elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
Wire.beginTransmission(MPU);
Wire.write(0x43); // Gyro data first register address 0x43
Wire.endTransmission(false);
Wire.requestFrom(MPU, 6, true); // Read 4 registers total, each axis value is stored in 2 registers
GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
// Correct the outputs with the calculated error values
GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56)
GyroY = GyroY - 2; // GyroErrorY ~(2)
GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8)
//Average angular speed
int Resultant;
int squareRAW;
squareRAW = sq(GyroX)+sq(GyroY);
Resultant = sqrt(squareRAW); //resultant angualar speed of x-axis and y-axis
//tft.setTextColor(ILI9341_WHITE,ILI9341_BLACK); tft.setTextSize(1);
//tft.print("Angular Velocity = ");
tft.setCursor(165,5);
tft.print(Resultant);
//tft.println(" (deg/sec) ");
Serial.print("Angular Velocity = ");
Serial.print(Resultant);
Serial.println(" (deg/sec) ");
// === Read force sensitive resistor data === //
fsrReading = analogRead(fsrPin);
//Serial.print("Analog reading = ");
//Serial.println(fsrReading);
// analog voltage reading ranges from about 0 to 1023 which maps to 0V to 5V (= 5000mV)
fsrVoltage = map(fsrReading, 0, 1023, 0, 5000);
//Serial.print("Voltage reading in mV = ");
//Serial.println(fsrVoltage);
if (fsrVoltage == 0)
{
tft.setCursor(130,18);
tft.print("0");
Serial.println("Force in Forearm = 0 N");
} else {
// The voltage = Vcc * R / (R + FSR) where R = 10K and Vcc = 5V
// so FSR = ((Vcc - V) * R) / V
fsrResistance = 5000 - fsrVoltage; // fsrVoltage is in millivolts so 5V = 5000mV
fsrResistance *= 10000; // 10K resistor
fsrResistance /= fsrVoltage;
//Serial.print("FSR resistance in ohms = ");
//Serial.println(fsrResistance);
fsrConductance = 1000000; // we measure in micromhos so
fsrConductance /= fsrResistance;
//Serial.print("Conductance in microMhos: ");
//Serial.println(fsrConductance);
// Use the two FSR guide graphs to approximate the force
if (fsrConductance <= 1000) {
fsrForce = fsrConductance / 80;
tft.setCursor(130,18);
tft.print(fsrForce);
//tft.println(" N");
Serial.print("Force in Forearm: ");
Serial.print(fsrForce);
Serial.println(" N");
} else {
fsrForce = fsrConductance - 1000;
fsrForce /= 30;
tft.setCursor(130,18);
tft.print(fsrForce);
//tft.println(" N");
Serial.print("Force in Forearm: ");
Serial.print(fsrForce);
Serial.println(" N");
}
}
Serial.println("--------------------");
delay(1000);
}
I have added the following code to plot the graph, but I'm not really sure how the library works for TFT screen in order for me to plot a proper graph.
void graph (void){
int y1, y2, z1, z2;
for (int x=1; x<319; x++){
y2 = map(Resultant, 0, 1023, 0, 240);
z2 = map(fsrForce, 0, 1023, 0, 240);
tft.drawLine(x,y1,x+1,y2,ILI9341_BLUE);
tft.drawLine(x,y1,x+1,y2,ILI9341_RED);
y1 = y2;
z1 = z2;
}
}
I would really appreciate if someone could explain to me how I can move on with the plotting of the line graph for my project. Thank you!!!