I am currently working on a project with a friend of mine, our goal is to make some kind of underground silo with a rocket inside it and a processing application to be able to launch the garden from my PC. The arduino's code works perfectly but I am having trouble with the processing sketch. The problem I have is that I can't find a way to send the launch code's textfield input directly to the arduino when I press the enter key.
What happens is that the code seems to be sending the code randomly even if I didn't press the enter key. I would love someone's help with my project because I would love taking it to an end!
Here is my current Processing code :
import processing.serial.*;
import controlP5.*;
Serial arduinoPort;
ControlP5 cp5;
int textFieldWidth = 200;
int buttonWidth = 100;
String launchCode = "7tRfKp9Z";
void setup() {
size(300, 400);
cp5 = new ControlP5(this);
// Add temperature and humidity displays
cp5.addTextlabel("tempLabel")
.setText("Temperature: ")
.setPosition(50, 50)
.setColorValue(0);
cp5.addTextlabel("humidityLabel")
.setText("Humidity: ")
.setPosition(50, 70)
.setColorValue(0);
cp5.addTextfield("launchCode")
.setPosition(50, 100)
.setSize(textFieldWidth, 20)
.addCallback(event -> {
if (event.getAction() == ControlP5.ACTION_ENTER) {
sendCode();
}
});
cp5.addButton("launchButton")
.setPosition(50, 130)
.setSize(buttonWidth, 20)
.setLabel("Launch")
.setColorBackground(color(0, 255, 0));
cp5.addButton("closeButton")
.setPosition(50 + buttonWidth + 10, 130)
.setSize(buttonWidth, 20)
.setLabel("Close")
.setColorBackground(color(255, 0, 0));
// Add port selection dropdown
DropdownList portList = cp5.addDropdownList("portList")
.setPosition(50, 170)
.setSize(textFieldWidth, 100);
for (String port : Serial.list()) {
portList.addItem(port, port);
}
// Connect to the selected port
portList.addCallback(event -> {
if (event.getAction() == ControlP5.ACTION_BROADCAST) {
String portName = cp5.get(DropdownList.class, "portList").getItem((int)event.getController().getValue()).get("name").toString();
if (arduinoPort != null) {
arduinoPort.stop();
}
arduinoPort = new Serial(this, portName, 9600);
}
});
}
void draw() {
background(255);
// Update temperature and humidity displays
if (arduinoPort != null && arduinoPort.available() > 0) {
String input = arduinoPort.readStringUntil('\n');
if (input != null) {
input = input.trim();
if (input.startsWith("T = ")) {
float temp = parseFloat(input.substring(4));
cp5.get(Textlabel.class, "tempLabel").setText(String.format("Temperature: %.1f", temp));
} else if (input.startsWith("H = ")) {
float humidity = parseFloat(input.substring(4));
cp5.get(Textlabel.class, "humidityLabel").setText(String.format("Humidity: %.1f", humidity));
}
}
}
}
void sendCode() {
String codeInput = cp5.get(Textfield.class, "launchCode").getText().trim();
println(codeInput);
arduinoPort.write(codeInput);
}
void launchButton() {
arduinoPort.write("launch\n");
}
void closeButton() {
arduinoPort.write("close\n");
}
And if this can help (we never know), the functional arduino code :
#include <Servo.h>
#include <dht_nonblocking.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );
#define IGNITION_PIN 7
#define NUM_HATCHES 1
#define HATCH_PINS {3}
#define HATCH_OPEN_ANGLE 90
#define HATCH_CLOSE_ANGLE 0
#define HATCH_SPEED 90
const String CODE = "7tRfKp9Z";
const String CLOSE_COMMAND = "close";
const String LAUNCH_COMMAND = "launch";
Servo hatches[NUM_HATCHES];
int hatchPins[NUM_HATCHES] = HATCH_PINS;
bool codeCorrect = false;
void setup() {
Serial.begin(9600);
pinMode(IGNITION_PIN, OUTPUT);
for (int i = 0; i < NUM_HATCHES; i++) {
hatches[i].attach(hatchPins[i]);
pinMode(hatchPins[i], OUTPUT);
}
}
void loop() {
float temperature;
float humidity;
if( measure_environment( &temperature, &humidity ) == true ) {
if (Serial.available() > 0) {
Serial.print( "T = " );
Serial.print( temperature, 1 );
Serial.print( ", H = " );
Serial.print( humidity, 1 );
}
}
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
if (input == CODE) {
openHatches();
} else if (input == CLOSE_COMMAND) {
closeHatches();
digitalWrite(IGNITION_PIN, LOW);
} else if (input == LAUNCH_COMMAND) {
digitalWrite(IGNITION_PIN, HIGH);
delay(3000);
digitalWrite(IGNITION_PIN, LOW);
}
}
}
void openHatches() {
for (int h = HATCH_CLOSE_ANGLE; h < HATCH_OPEN_ANGLE; h++){
for (int i = 0; i < NUM_HATCHES; i++) {
hatches[i].write(h);
}
int speed = map(HATCH_SPEED, 0, 100, 1000, 0);
delay(speed);
}
}
void closeHatches() {
for (int h = HATCH_OPEN_ANGLE; h > HATCH_CLOSE_ANGLE; h--){
for (int i = 0; i < NUM_HATCHES; i++) {
hatches[i].write(h);
}
if (h > 30/100.0 * HATCH_OPEN_ANGLE) {
}
else {
int speed = map(HATCH_SPEED, 0, 100, 500, 0);
delay(speed);
}
}
}
static bool measure_environment( float *temperature, float *humidity ) {
static unsigned long measurement_timestamp = millis( );
/* Measure once every four seconds. */
if( millis( ) - measurement_timestamp > 3000ul ) {
if( dht_sensor.measure( temperature, humidity ) == true ) {
measurement_timestamp = millis( );
return( true );
}
}
return( false );
}
Please consider the following demo and see if you can apply it to your project. When the 'launch' button is hit the demo sends a byte character 'l' (ascii value 108) to the Arduino which promptly sends it back to the Processing app so that you can see that it got sent and was received. Hopefully something similar will help you launch your rocket. The Arduino code is also shown.
Processing code:
Arduino code: