I want to send some data from my PC to my Arduino using Serial.
This is my PC python code, which works.
import psutil
import serial
import time
import GPUtil
# Initialize the serial connection
arduino = serial.Serial('COM5', 9600) # Replace 'COMX' with the correct COM port
while True:
# Get CPU and RAM usage
cpu_percent = psutil.cpu_percent()
ram_percent = psutil.virtual_memory().percent
# Get GPU temperature
gpu_temperature = None
try:
# Assuming you have only one GPU. You can modify the code if you have multiple GPUs.
gpu = GPUtil.getGPUs()[0]
gpu_temperature = gpu.temperature
except Exception as e:
print(f"Error getting GPU temperature: {e}")
# Format the data as a single string
data = f"CPU: {cpu_percent:.2f}%\nRAM: {ram_percent:.2f}%\nGPU Temp: {gpu_temperature or 'N/A'}\n"
# Send data to Arduino
print("Sending data to Arduino: ", data)
arduino.write(data.encode())
# Delay to prevent flooding the Arduino
time.sleep(1)
This is the Arduino code.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 16, 2); // Adjust the I2C address if needed
unsigned long lastDataReceivedTime = 0;
const unsigned long backlightTimeout = 10000; // 10 seconds in milliseconds
// Define the pins for the RGB LED
const int redPin = 11; // Red LED connected to digital pin 11
const int greenPin = 9; // Green LED connected to digital pin 9
const int bluePin = 10; // Blue LED connected to digital pin 10
// Duration for each color transition in milliseconds
const unsigned long transitionDuration = 1500; // 2 seconds per transition
unsigned long startTime = 0; // Time when the transition started
int startRed, startGreen, startBlue; // Starting color values
int endRed, endGreen, endBlue; // Ending color values
enum ColorTransitionState {
RED_TO_GREEN,
GREEN_TO_BLUE,
BLUE_TO_RED
};
ColorTransitionState currentTransitionState = RED_TO_GREEN;
unsigned long transitionStartTime = 0;
String cpuUsage;
String ramUsage;
bool isCPURamDataReceived = false;
void setup() {
// Initialize the RGB pins as OUTPUT
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
lcd.init();
lcd.clear();
Serial.begin(9600);
}
void loop() {
ledloop();
// Non-blocking Serial data reception
while (Serial.available() > 0) {
char c = Serial.read();
if (c == '\n') {
processSerialData();
} else {
if (!isCPURamDataReceived) {
// Append the characters to the CPU data string
cpuUsage += c;
} else {
// Append the characters to the RAM data string
ramUsage += c;
}
}
}
if (millis() - lastDataReceivedTime >= backlightTimeout) {
lcd.noBacklight(); // Turn off the backlight
} else {
lcd.backlight();
}
}
void processSerialData() {
if (!isCPURamDataReceived) {
// CPU data is received, switch to RAM data
isCPURamDataReceived = true;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(cpuUsage);
lcd.setCursor(0, 1);
lcd.print(ramUsage);
// Reset data variables
cpuUsage = "";
ramUsage = "";
isCPURamDataReceived = false;
}
lastDataReceivedTime = millis();
}
void ledloop() {
unsigned long currentTime = millis();
if (currentTransitionState == RED_TO_GREEN &&
currentTime - transitionStartTime >= transitionDuration) {
currentTransitionState = GREEN_TO_BLUE;
transitionStartTime = currentTime;
} else if (currentTransitionState == GREEN_TO_BLUE &&
currentTime - transitionStartTime >= transitionDuration) {
currentTransitionState = BLUE_TO_RED;
transitionStartTime = currentTime;
} else if (currentTransitionState == BLUE_TO_RED &&
currentTime - transitionStartTime >= transitionDuration) {
currentTransitionState = RED_TO_GREEN;
transitionStartTime = currentTime;
}
switch (currentTransitionState) {
case RED_TO_GREEN:
startRed = 0; startGreen = 255; startBlue = 255;
endRed = 255; endGreen = 0; endBlue = 255;
break;
case GREEN_TO_BLUE:
startRed = 255; startGreen = 0; startBlue = 255;
endRed = 255; endGreen = 255; endBlue = 0;
break;
case BLUE_TO_RED:
startRed = 255; startGreen = 255; startBlue = 0;
endRed = 0; endGreen = 255; endBlue = 255;
break;
}
float progress = (currentTime - transitionStartTime) / (float)transitionDuration;
int redValue = startRed + (endRed - startRed) * progress;
int greenValue = startGreen + (endGreen - startGreen) * progress;
int blueValue = startBlue + (endBlue - startBlue) * progress;
analogWrite(redPin, redValue);
analogWrite(greenPin, greenValue);
analogWrite(bluePin, blueValue);
}
It all works, I'm receiving CPU, RAM, and GPU data. However, instead of displaying the GPU data on the LCD, I want it on a bargraph.
So I tried this:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 16, 2); // Adjust the I2C address if needed
unsigned long lastDataReceivedTime = 0;
const unsigned long backlightTimeout = 10000; // 10 seconds in milliseconds
const int ledPins[] = {2, 3, 4, 5, 6, 7, 8, 13}; // Define the LED pins
const int numLeds = sizeof(ledPins) / sizeof(ledPins[0]);
// Define the pins for the RGB LED
const int redPin = 11; // Red LED connected to digital pin 11
const int greenPin = 9; // Green LED connected to digital pin 9
const int bluePin = 10; // Blue LED connected to digital pin 10
// Duration for each color transition in milliseconds
const unsigned long transitionDuration = 1500; // 2 seconds per transition
unsigned long startTime = 0; // Time when the transition started
int startRed, startGreen, startBlue; // Starting color values
int endRed, endGreen, endBlue; // Ending color values
enum ColorTransitionState {
RED_TO_GREEN,
GREEN_TO_BLUE,
BLUE_TO_RED
};
ColorTransitionState currentTransitionState = RED_TO_GREEN;
unsigned long transitionStartTime = 0;
String cpuUsage;
String ramUsage;
String gpuTemp;
bool isDataReceived = false;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
lcd.init();
lcd.clear();
Serial.begin(9600);
// Set LED pins as OUTPUT
for (int i = 0; i < numLeds; ++i) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
ledloop();
// Non-blocking Serial data reception
while (Serial.available() > 0) {
char c = Serial.read();
if (c == '\n') {
processSerialData();
} else {
if (!isDataReceived) {
// Append the characters to the CPU data string
cpuUsage += c;
} else {
// Append the characters to the RAM data string
ramUsage += c;
}
}
}
if (millis() - lastDataReceivedTime >= backlightTimeout) {
lcd.noBacklight(); // Turn off the backlight
} else {
lcd.backlight();
}
displayGPUTemperatureBar();
}
void processSerialData() {
if (!isDataReceived) {
// CPU data is received, switch to RAM data
isDataReceived = true;
} else {
// RAM data is received, switch to GPU data
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(cpuUsage);
lcd.setCursor(0, 1);
lcd.print(ramUsage);
// Reset data variables
cpuUsage = "";
ramUsage = "";
gpuTemp = "";
isDataReceived = false;
}
lastDataReceivedTime = millis();
}
void displayGPUTemperatureBar() {
if (isDataReceived) {
int gpuTemperature = gpuTemp.toInt();
int ledsToLight = map(gpuTemperature, 0, 100, 0, numLeds);
// Turn on LEDs based on the GPU temperature
for (int i = 0; i < numLeds; ++i) {
if (i < ledsToLight) {
digitalWrite(ledPins[i], HIGH);
} else {
digitalWrite(ledPins[i], LOW);
}
}
}
}
void ledloop() {
unsigned long currentTime = millis();
if (currentTransitionState == RED_TO_GREEN &&
currentTime - transitionStartTime >= transitionDuration) {
currentTransitionState = GREEN_TO_BLUE;
transitionStartTime = currentTime;
} else if (currentTransitionState == GREEN_TO_BLUE &&
currentTime - transitionStartTime >= transitionDuration) {
currentTransitionState = BLUE_TO_RED;
transitionStartTime = currentTime;
} else if (currentTransitionState == BLUE_TO_RED &&
currentTime - transitionStartTime >= transitionDuration) {
currentTransitionState = RED_TO_GREEN;
transitionStartTime = currentTime;
}
switch (currentTransitionState) {
case RED_TO_GREEN:
startRed = 0; startGreen = 255; startBlue = 255;
endRed = 255; endGreen = 0; endBlue = 255;
break;
case GREEN_TO_BLUE:
startRed = 255; startGreen = 0; startBlue = 255;
endRed = 255; endGreen = 255; endBlue = 0;
break;
case BLUE_TO_RED:
startRed = 255; startGreen = 255; startBlue = 0;
endRed = 0; endGreen = 255; endBlue = 255;
break;
}
float progress = (currentTime - transitionStartTime) / (float)transitionDuration;
int redValue = startRed + (endRed - startRed) * progress;
int greenValue = startGreen + (endGreen - startGreen) * progress;
int blueValue = startBlue + (endBlue - startBlue) * progress;
analogWrite(redPin, redValue);
analogWrite(greenPin, greenValue);
analogWrite(bluePin, blueValue);
}
But it still doesn't display on the bargraph, only the LCD.
What have I overlooked?