NRF24L01 is not sending valid data - arduino
I have a problem with NRF24L01
I'm building a weather station and I ran into a problem, I can't send the correct value from each sensor to the receiver. The values in the char are sending correctly but the float value is not, I keep getting the value 656677.37
Here is the transmitter code
//DallasTemperature
#include <OneWire.h>
#include <DallasTemperature.h>
//DHT11
#include <DHT.h>
//BMP280
#include <Wire.h>
#include "i2c.h"
#include "i2c_BMP280.h"
#include <MQ135.h>
//NRF24l01 pn ln
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//============================================[Pin Definitions]=============================================
#define MQ135_PIN A1
#define DHT_PIN 2
#define DHTTYPE DHT11
#define ONE_WIRE_BUS 3
#define LDR_PIN A0
#define RAIN_PIN A2
//============================================[Global defines]=============================================
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DHT dht(DHT_PIN, DHTTYPE);
BMP280 bmp280;
MQ135 mq135_sensor(MQ135_PIN);
RF24 radio(9, 10); // CE, CSN
//============================================[Global variables]=============================================
float temp_DALLAS;
float humidity_DHT;
float temperature_DHT;
float hic;
float temperature_BMP;
float pascal_BMP;
float rzero_MQ135;
float correctedRZero_MQ135;
float resistance_MQ135;
float ppm_MQ135;
float correctedPPM_MQ135;
#define MAX_ADC_READING 1023
#define ADC_REF_VOLTAGE 5.0
#define REF_RESISTANCE 5030 // measure this for best results
#define LUX_CALC_SCALAR 12518931
#define LUX_CALC_EXPONENT -1.405
int ldrRawData;
float resistorVoltage, ldrVoltage;
float ldrResistance;
float ldrLux;
int rainRawData;
const byte address[6] = "00001";
#define nodechar 20
#define typechar 20
//#define valuechar 20
//#define unitchar 20
struct Template {
char node[nodechar];
char type[typechar];
//char value[valuechar] = "\0";
//char unit[unitchar];
float value;
};Template myStruct;
unsigned int h_old = 0;
unsigned int h_new = 0;
unsigned int t_old = 0;
unsigned int t_new = 0;
unsigned int hic_old = 0;
unsigned int hic_new = 0;
unsigned int pbmp_old = 0;
unsigned int pbmp_new = 0;
unsigned int tbmp_old = 0;
unsigned int tbmp_new = 0;
unsigned int rzMQ135_old = 0;
unsigned int rzMQ135_new = 0;
unsigned int crzMQ135_old = 0;
unsigned int crzMQ135_new = 0;
unsigned int rMQ135_old = 0;
unsigned int rMQ135_new = 0;
unsigned int ppmMQ135_old = 0;
unsigned int ppmMQ135_new = 0;
unsigned int cppmMQ135_old = 0;
unsigned int cppmMQ135_new = 0;
unsigned int tdallas_old = 0;
unsigned int tdallas_new = 0;
unsigned int ldr_old = 0;
unsigned int ldr_new = 0;
unsigned int rain_old = 0;
unsigned int rain_new = 0;
void setup(){
Serial.begin(115200);
dht.begin();
Serial.print("Probe BMP280: ");
if(bmp280.initialize()) Serial.println("Sensor found");
else Serial.println("Sensor missing");
bmp280.setEnabled(0);
bmp280.triggerMeasurement();
Serial.print("Locating devices...");
sensors.begin();
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" devices.");
if (!radio.begin()) Serial.println(F("radio hardware is not responding!!"));
else Serial.println(F("radio hardware is responding!!"));
radio.setPALevel(RF24_PA_MAX);
//radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
String stringOne2 = "1;Meteo";
stringOne2.toCharArray(myStruct.node, nodechar);
}
void loop(){
humidity_DHT = dht.readHumidity();
temperature_DHT = dht.readTemperature();
hic = dht.computeHeatIndex(temperature_DHT, humidity_DHT, false);
bmp280.awaitMeasurement();
bmp280.getTemperature(temperature_BMP);
bmp280.getPressure(pascal_BMP);
static float meters, metersold;
bmp280.getAltitude(meters);
metersold = (metersold * 10 + meters)/11;
bmp280.triggerMeasurement();
rzero_MQ135 = mq135_sensor.getRZero();
correctedRZero_MQ135 = mq135_sensor.getCorrectedRZero(temperature_DHT, humidity_DHT);
resistance_MQ135 = mq135_sensor.getResistance();
ppm_MQ135 = mq135_sensor.getPPM();
correctedPPM_MQ135 = mq135_sensor.getCorrectedPPM(temperature_DHT, humidity_DHT);
sensors.requestTemperatures();
// method 2 - faster
temp_DALLAS = sensors.getTempCByIndex(0);
ldrRawData = analogRead(LDR_PIN);
resistorVoltage = (float)ldrRawData / MAX_ADC_READING * ADC_REF_VOLTAGE;
ldrVoltage = ADC_REF_VOLTAGE - resistorVoltage;
ldrResistance = ldrVoltage/resistorVoltage * REF_RESISTANCE;
ldrLux = LUX_CALC_SCALAR * pow(ldrResistance, LUX_CALC_EXPONENT);
rainRawData = analogRead(RAIN_PIN);
rainRawData = 1024 - rainRawData;
/*Serial.print(F("Humidity: "));
Serial.print(humidity_DHT);
Serial.print(F("% Temperature: "));
Serial.print(temperature_DHT);
Serial.print(F("°C "));
Serial.print(F(" Heat index: "));
Serial.print(hic);
Serial.print(F("°C "));
Serial.print(" HeightPT1: ");
Serial.print(metersold);
Serial.print(" m; Height: ");
Serial.print(meters);
Serial.print(" Pressure: ");
Serial.print(pascal_BMP);
Serial.print(" Pa; T: ");
Serial.print(temperature_BMP);
Serial.print(" C ");
Serial.print("MQ135 RZero: ");
Serial.print(rzero_MQ135);
Serial.print(" Corrected RZero: ");
Serial.print(correctedRZero_MQ135);
Serial.print(" Resistance: ");
Serial.print(resistance_MQ135);
Serial.print(" PPM: ");
Serial.print(ppm_MQ135);
Serial.print("ppm");
Serial.print(" Corrected PPM: ");
Serial.print(correctedPPM_MQ135);
Serial.print("ppm ");
Serial.print("Temp C: ");
Serial.print(temp_DALLAS);
Serial.print(" LDR Raw Data: ");
Serial.print(ldrRawData);
Serial.print(" LDR Voltage: ");
Serial.print(ldrVoltage);
Serial.print(" volts LDR Resistance: ");
Serial.print(ldrResistance);
Serial.print(" Ohms LDR Illuminance: ");
Serial.print(ldrLux);
Serial.print(" lux Rain:");
Serial.println(rainRawData);*/
h_new = humidity_DHT;
if(h_new != h_old){
//myStruct.type = 1;
String stringOne = "HUMIDITY_DHT";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "%";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = h_new;
radio.write(&myStruct, sizeof(myStruct));
h_old = h_new;
}
t_new = temperature_DHT;
if(t_new != t_old){
// myStruct.type = 2;
String stringOne = "TEMP_DHT";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "°C";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = t_new;
radio.write(&myStruct, sizeof(myStruct));
t_old = t_new;
}
hic_new = hic;
if(hic_new != hic_old){
//myStruct.type = 3;
String stringOne = "HIC_DHT";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "°C";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = hic_new;
radio.write(&myStruct, sizeof(myStruct));
hic_old = hic_new;
}
pbmp_new = pascal_BMP;
if(pbmp_new != pbmp_old){
//myStruct.type = 4;
String stringOne = "PASCAL_BMP";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "Pa";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = pbmp_new;
radio.write(&myStruct, sizeof(myStruct));
pbmp_old = pbmp_new;
}
tbmp_new = temperature_BMP;
if(tbmp_new != tbmp_old){
//myStruct.type = 5;
String stringOne = "TEMP_BMP";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "°C";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = tbmp_new;
radio.write(&myStruct, sizeof(myStruct));
tbmp_old = tbmp_new;
}
rzMQ135_new = rzero_MQ135;
if(rzMQ135_new != rzMQ135_old){
// myStruct.type = 6;
String stringOne = "RZ_MQ135";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "raw";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = rzMQ135_new;
radio.write(&myStruct, sizeof(myStruct));
rzMQ135_old = rzMQ135_new;
}
crzMQ135_new = correctedRZero_MQ135;
if(crzMQ135_new != crzMQ135_old){
//myStruct.type = 7;
String stringOne = "CRZ_MQ135";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "raw";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = crzMQ135_new;
radio.write(&myStruct, sizeof(myStruct));
crzMQ135_old = crzMQ135_new;
}
rMQ135_new = resistance_MQ135;
if(rMQ135_new != rMQ135_old){
//myStruct.type = 8;
String stringOne = "R_MQ135";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "R";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = rMQ135_new;
radio.write(&myStruct, sizeof(myStruct));
rMQ135_old = rMQ135_new;
}
ppmMQ135_new = ppm_MQ135;
if(ppmMQ135_new != ppmMQ135_old){
//myStruct.type = 9;
String stringOne = "PPM_MQ135";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "ppm";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = ppmMQ135_new;
radio.write(&myStruct, sizeof(myStruct));
ppmMQ135_old = ppmMQ135_new;
}
cppmMQ135_new = correctedPPM_MQ135;
if(cppmMQ135_new != cppmMQ135_old){
//myStruct.type = 10;
String stringOne = "CPPM_MQ135";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "ppm";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = cppmMQ135_new;
radio.write(&myStruct, sizeof(myStruct));
cppmMQ135_old = cppmMQ135_new;
}
tdallas_new = temp_DALLAS;
if(tdallas_new != tdallas_old){
//myStruct.type = 10;
String stringOne = "Temp_Dallas";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "°C";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = tdallas_new;
radio.write(&myStruct, sizeof(myStruct));
tdallas_old = tdallas_new;
}
ldr_new = ldrLux;
if(ldr_new != ldr_old){
//myStruct.type = 11;
String stringOne = "LDR";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "lux";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = ldr_new;
radio.write(&myStruct, sizeof(myStruct));
ldr_old = ldr_new;
}
rain_new = rainRawData;
if(rain_new != rain_old){
// myStruct.type = 12;
String stringOne = "RAIN";
stringOne.toCharArray(myStruct.type, typechar);
/*String stringOne2 = "%";
stringOne2.toCharArray(myStruct.unit, unitchar);*/
myStruct.value = rain_new;
radio.write(&myStruct, sizeof(myStruct));
rain_old = rain_new;
}
delay(500);
}
Here is the receiver code
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define WIRE Wire
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &WIRE);
RF24 radio(9,10); // CE, CSN
const byte address[6] = "00001";
#define nodechar 20
#define typechar 20
//#define unitchar 20
//#define valuechar 20
struct MyStruct{
char node[nodechar];
char type[typechar];
//char unit[unitchar];
float value;
};
void setup(){
Serial.begin(115200);
Serial.println("OLED FeatherWing test");
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
if(!radio.begin()) Serial.println(F("radio hardware is not responding!!"));
else Serial.println(F("radio hardware is responding!!"));
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MAX);
radio.startListening();
display.display();
// Clear the buffer.
display.clearDisplay();
display.display();
}
void loop(){
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.print("IP: 10.0.0.243\n");
if(radio.available()){
MyStruct myStruct;
radio.read(&myStruct, sizeof(myStruct));
//char text[32] = "";
//radio.read(&text, sizeof(text));
Serial.print(myStruct.node);
Serial.print(" - ");
Serial.print(myStruct.type);
Serial.print(" - ");
Serial.println(myStruct.value);
//Serial.print(" - ");
//Serial.println(myStruct.unit);
//display.clearDisplay();
//display.setTextSize(1);
//display.setTextColor(SSD1306_WHITE);
display.setCursor(1,1);
display.print("\nID: ");
display.print(myStruct.node);
display.print("\nType:");
display.print(myStruct.type);
display.print("\nValue:");
display.println(myStruct.value);
//display.println("Sending val #0");
//display.setCursor(0,0);
display.display(); // actually display all of the above
}
}
I can't send the correct float value, without sending data I get the correct values from the sensors
maybe struct alignment problem :
try this on each side :
struct __attribute__((__packed__)) MyStruct{
char node[nodechar];
char type[typechar];
//char unit[unitchar];
float value;
};
Related
Firebase Realtime Database not showing anything with ESP32 CAM
I'm trying to send images from my ESP32 Cam to my Firebase Realtime Database, this is my .ino code const char* ssid = "xxx"; const char* password = "xxx"; String FIREBASE_HOST = "xxx"; String FIREBASE_AUTH = "xxx"; #include "FirebaseESP32.h" FirebaseData firebaseData; #include <WiFi.h> #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include "Base64.h" #include "esp_camera.h" #define CAMERA_MODEL_AI_THINKER #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); Serial.begin(115200); WiFi.begin(ssid, password); long int StartTime=millis(); while (WiFi.status() != WL_CONNECTED) { delay(500); if ((StartTime+10000) < millis()) break; } if (WiFi.status() == WL_CONNECTED) { char* apssid = "ESP32-CAM"; char* appassword = "12345678"; WiFi.softAP((WiFi.localIP().toString()+"_"+(String)apssid).c_str(), appassword); } else { return; } camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; if(psramFound()){ config.frame_size = FRAMESIZE_UXGA; config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; config.fb_count = 1; } esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { delay(1000); ESP.restart(); } sensor_t * s = esp_camera_sensor_get(); s->set_framesize(s, FRAMESIZE_CIF); Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); Firebase.reconnectWiFi(true); Firebase.setMaxRetry(firebaseData, 3); Firebase.setMaxErrorQueue(firebaseData, 30); Firebase.enableClassicRequest(firebaseData, true); String jsonData = "{\"photo\":\"" + Photo2Base64() + "\"}"; String photoPath = "/esp32-cam"; Serial.println(Photo2Base64()); Firebase.setString(firebaseData, "/esp32-cam", Photo2Base64()); } void loop() { delay(10000); } String Photo2Base64() { camera_fb_t * fb = NULL; fb = esp_camera_fb_get(); if(!fb) { return ""; } String imageFile = "data:image/jpeg;base64,"; char *input = (char *)fb->buf; char output[base64_enc_len(3)]; for (int i=0;i<fb->len;i++) { base64_encode(output, (input++), 3); if (i%3==0) imageFile += urlencode(String(output)); } esp_camera_fb_return(fb); return imageFile; } String urlencode(String str) { String encodedString=""; char c; char code0; char code1; char code2; for (int i =0; i < str.length(); i++){ c=str.charAt(i); if (c == ' '){ encodedString+= '+'; } else if (isalnum(c)){ encodedString+=c; } else{ code1=(c & 0xf)+'0'; if ((c & 0xf) >9){ code1=(c & 0xf) - 10 + 'A'; } c=(c>>4)&0xf; code0=c+'0'; if (c > 9){ code0=c - 10 + 'A'; } code2='\0'; encodedString+='%'; encodedString+=code0; encodedString+=code1; } yield(); } return encodedString; } The serial monitor shows the Base64 image, even putting into a browser, the image appears... Serial Monitor But does not appear in the Real Time Database... Problema de Firebase When I compile the code, there is no error, can you guys help me?
Trying to add functions on ESP32CAM CameraWebServer Example Code
I am trying to control ESP32CAM's I/O pins and also getting view from camera. For this purpose, I tried to edit CameraWebServer example like this: #include "esp_camera.h" #include <WiFi.h> // // WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality // Ensure ESP32 Wrover Module or other board with PSRAM is selected // Partial images will be transmitted if image exceeds buffer size // // Select camera model //#define CAMERA_MODEL_WROVER_KIT // Has PSRAM //#define CAMERA_MODEL_ESP_EYE // Has PSRAM //#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM //#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM //#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM //#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM #define CAMERA_MODEL_AI_THINKER // Has PSRAM //#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM #include "camera_pins.h" WiFiServer espServer(81); String request; const char* ssid = "VODAFONE_9D53"; const char* password = "fc1f1fff"; void startCameraServer(); void setup() { Serial.begin(115200); Serial.setDebugOutput(true); Serial.println(); pinMode(12, OUTPUT); pinMode(13, OUTPUT); digitalWrite(4, LOW); camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; // if PSRAM IC present, init with UXGA resolution and higher JPEG quality // for larger pre-allocated frame buffer. if(psramFound()){ config.frame_size = FRAMESIZE_UXGA; config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; config.fb_count = 1; } #if defined(CAMERA_MODEL_ESP_EYE) pinMode(13, INPUT_PULLUP); pinMode(14, INPUT_PULLUP); #endif // camera init esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } sensor_t * s = esp_camera_sensor_get(); // initial sensors are flipped vertically and colors are a bit saturated if (s->id.PID == OV3660_PID) { s->set_vflip(s, 1); // flip it back s->set_brightness(s, 1); // up the brightness just a bit s->set_saturation(s, -2); // lower the saturation } // drop down frame size for higher initial frame rate s->set_framesize(s, FRAMESIZE_QVGA); #if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM) s->set_vflip(s, 1); s->set_hmirror(s, 1); #endif WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); startCameraServer(); Serial.print("Camera Ready! Use 'http://"); Serial.print(WiFi.localIP()); Serial.println("' to connect"); delay(2000); espServer.begin(); } void loop() { WiFiClient client = espServer.available(); /* Check if a client is available */ if(!client) { return; } Serial.println("New Client!!!"); boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); request += c; Serial.write(c); if (c == '\n' && currentLineIsBlank) { if (request.indexOf("/GPIO12ON") != -1) { Serial.println("GPIO12 LED is ON"); digitalWrite(12, HIGH); Serial.printf("12 HIGH"); } if (request.indexOf("/GPIO12OFF") != -1) { Serial.println("GPIO12 LED is OFF"); digitalWrite(12, LOW); Serial.printf("12 LOW"); } if (request.indexOf("/GPIO13ON") != -1) { Serial.println("GPIO13 LED is ON"); digitalWrite(13, HIGH); Serial.printf("13 HIGH"); } if (request.indexOf("/GPIO13OFF") != -1) { Serial.println("GPIO13 LED is OFF"); digitalWrite(13, LOW); Serial.printf("13 LOW"); } client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // IMPORTANT break; } if(c == '\n') { currentLineIsBlank = true; } else if(c != '\r') { currentLineIsBlank = false; } //client.print("\n"); } } delay(1); request = ""; //client.flush(); client.stop(); Serial.println("Client disconnected"); Serial.print("\n"); } I did 81 port because i want to use camera and I/O control on ngrok. (I can only open 1 port on ngrok, stream URL is already on 81 port so i tried to move I/O control part to 81 port) I can control I/O pins but i cant use camera on xxx.xxx.x.xx:81/stream URL. Can you help me ?
I got some help and found this. First of all, function is need to be defined in the app_httpd.cpp like this: static esp_err_t gpio12On_handler(httpd_req_t *req){ Serial.println("ON, 12.port HIGH"); digitalWrite(12, HIGH); return httpd_resp_send(req, NULL, 0); } And then in the startCameraServer() function you need to declare the URI like this: httpd_uri_t gpio12On_uri = { .uri = "/gpio12On", .method = HTTP_GET, .handler = gpio12On_handler, .user_ctx = NULL }; Finally, you can add the function to server with this code: httpd_register_uri_handler(camera_httpd, &ledOn_uri); Note: httpd_register_uri_handler comand needs to come after the httpd_start command If you want to have this URI on the port 80 you need to use stream_httpd But if you want to use port 81 then you need to use camera_httpd Full code: #include "esp_http_server.h" #include "esp_timer.h" #include "esp_camera.h" #include "img_converters.h" #include "camera_index.h" #include "Arduino.h" #include "fb_gfx.h" #include "fd_forward.h" #include "fr_forward.h" #define ENROLL_CONFIRM_TIMES 5 #define FACE_ID_SAVE_NUMBER 7 #define FACE_COLOR_WHITE 0x00FFFFFF #define FACE_COLOR_BLACK 0x00000000 #define FACE_COLOR_RED 0x000000FF #define FACE_COLOR_GREEN 0x0000FF00 #define FACE_COLOR_BLUE 0x00FF0000 #define FACE_COLOR_YELLOW (FACE_COLOR_RED | FACE_COLOR_GREEN) #define FACE_COLOR_CYAN (FACE_COLOR_BLUE | FACE_COLOR_GREEN) #define FACE_COLOR_PURPLE (FACE_COLOR_BLUE | FACE_COLOR_RED) typedef struct { size_t size; //number of values used for filtering size_t index; //current value index size_t count; //value count int sum; int * values; //array to be filled with values } ra_filter_t; typedef struct { httpd_req_t *req; size_t len; } jpg_chunking_t; #define PART_BOUNDARY "123456789000000000000987654321" static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; static ra_filter_t ra_filter; httpd_handle_t stream_httpd = NULL; httpd_handle_t camera_httpd = NULL; static mtmn_config_t mtmn_config = {0}; static int8_t detection_enabled = 0; static int8_t recognition_enabled = 0; static int8_t is_enrolling = 0; static face_id_list id_list = {0}; static ra_filter_t * ra_filter_init(ra_filter_t * filter, size_t sample_size){ memset(filter, 0, sizeof(ra_filter_t)); filter->values = (int *)malloc(sample_size * sizeof(int)); if(!filter->values){ return NULL; } memset(filter->values, 0, sample_size * sizeof(int)); filter->size = sample_size; return filter; } static int ra_filter_run(ra_filter_t * filter, int value){ if(!filter->values){ return value; } filter->sum -= filter->values[filter->index]; filter->values[filter->index] = value; filter->sum += filter->values[filter->index]; filter->index++; filter->index = filter->index % filter->size; if (filter->count < filter->size) { filter->count++; } return filter->sum / filter->count; } static void rgb_print(dl_matrix3du_t *image_matrix, uint32_t color, const char * str){ fb_data_t fb; fb.width = image_matrix->w; fb.height = image_matrix->h; fb.data = image_matrix->item; fb.bytes_per_pixel = 3; fb.format = FB_BGR888; fb_gfx_print(&fb, (fb.width - (strlen(str) * 14)) / 2, 10, color, str); } static int rgb_printf(dl_matrix3du_t *image_matrix, uint32_t color, const char *format, ...){ char loc_buf[64]; char * temp = loc_buf; int len; va_list arg; va_list copy; va_start(arg, format); va_copy(copy, arg); len = vsnprintf(loc_buf, sizeof(loc_buf), format, arg); va_end(copy); if(len >= sizeof(loc_buf)){ temp = (char*)malloc(len+1); if(temp == NULL) { return 0; } } vsnprintf(temp, len+1, format, arg); va_end(arg); rgb_print(image_matrix, color, temp); if(len > 64){ free(temp); } return len; } static void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes, int face_id){ int x, y, w, h, i; uint32_t color = FACE_COLOR_YELLOW; if(face_id < 0){ color = FACE_COLOR_RED; } else if(face_id > 0){ color = FACE_COLOR_GREEN; } fb_data_t fb; fb.width = image_matrix->w; fb.height = image_matrix->h; fb.data = image_matrix->item; fb.bytes_per_pixel = 3; fb.format = FB_BGR888; for (i = 0; i < boxes->len; i++){ // rectangle box x = (int)boxes->box[i].box_p[0]; y = (int)boxes->box[i].box_p[1]; w = (int)boxes->box[i].box_p[2] - x + 1; h = (int)boxes->box[i].box_p[3] - y + 1; fb_gfx_drawFastHLine(&fb, x, y, w, color); fb_gfx_drawFastHLine(&fb, x, y+h-1, w, color); fb_gfx_drawFastVLine(&fb, x, y, h, color); fb_gfx_drawFastVLine(&fb, x+w-1, y, h, color); #if 0 // landmark int x0, y0, j; for (j = 0; j < 10; j+=2) { x0 = (int)boxes->landmark[i].landmark_p[j]; y0 = (int)boxes->landmark[i].landmark_p[j+1]; fb_gfx_fillRect(&fb, x0, y0, 3, 3, color); } #endif } } static int run_face_recognition(dl_matrix3du_t *image_matrix, box_array_t *net_boxes){ dl_matrix3du_t *aligned_face = NULL; int matched_id = 0; aligned_face = dl_matrix3du_alloc(1, FACE_WIDTH, FACE_HEIGHT, 3); if(!aligned_face){ Serial.println("Could not allocate face recognition buffer"); return matched_id; } if (align_face(net_boxes, image_matrix, aligned_face) == ESP_OK){ if (is_enrolling == 1){ int8_t left_sample_face = enroll_face(&id_list, aligned_face); if(left_sample_face == (ENROLL_CONFIRM_TIMES - 1)){ Serial.printf("Enrolling Face ID: %d\n", id_list.tail); } Serial.printf("Enrolling Face ID: %d sample %d\n", id_list.tail, ENROLL_CONFIRM_TIMES - left_sample_face); rgb_printf(image_matrix, FACE_COLOR_CYAN, "ID[%u] Sample[%u]", id_list.tail, ENROLL_CONFIRM_TIMES - left_sample_face); if (left_sample_face == 0){ is_enrolling = 0; Serial.printf("Enrolled Face ID: %d\n", id_list.tail); } } else { matched_id = recognize_face(&id_list, aligned_face); if (matched_id >= 0) { Serial.printf("Match Face ID: %u\n", matched_id); rgb_printf(image_matrix, FACE_COLOR_GREEN, "Hello Subject %u", matched_id); } else { Serial.println("No Match Found"); rgb_print(image_matrix, FACE_COLOR_RED, "Intruder Alert!"); matched_id = -1; } } } else { Serial.println("Face Not Aligned"); //rgb_print(image_matrix, FACE_COLOR_YELLOW, "Human Detected"); } dl_matrix3du_free(aligned_face); return matched_id; } static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){ jpg_chunking_t *j = (jpg_chunking_t *)arg; if(!index){ j->len = 0; } if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK){ return 0; } j->len += len; return len; } static esp_err_t capture_handler(httpd_req_t *req){ camera_fb_t * fb = NULL; esp_err_t res = ESP_OK; int64_t fr_start = esp_timer_get_time(); fb = esp_camera_fb_get(); if (!fb) { Serial.println("Camera capture failed"); httpd_resp_send_500(req); return ESP_FAIL; } httpd_resp_set_type(req, "image/jpeg"); httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg"); httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); size_t out_len, out_width, out_height; uint8_t * out_buf; bool s; bool detected = false; int face_id = 0; if(!detection_enabled || fb->width > 400){ size_t fb_len = 0; if(fb->format == PIXFORMAT_JPEG){ fb_len = fb->len; res = httpd_resp_send(req, (const char *)fb->buf, fb->len); } else { jpg_chunking_t jchunk = {req, 0}; res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk)?ESP_OK:ESP_FAIL; httpd_resp_send_chunk(req, NULL, 0); fb_len = jchunk.len; } esp_camera_fb_return(fb); int64_t fr_end = esp_timer_get_time(); Serial.printf("JPG: %uB %ums\n", (uint32_t)(fb_len), (uint32_t)((fr_end - fr_start)/1000)); return res; } dl_matrix3du_t *image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3); if (!image_matrix) { esp_camera_fb_return(fb); Serial.println("dl_matrix3du_alloc failed"); httpd_resp_send_500(req); return ESP_FAIL; } out_buf = image_matrix->item; out_len = fb->width * fb->height * 3; out_width = fb->width; out_height = fb->height; s = fmt2rgb888(fb->buf, fb->len, fb->format, out_buf); esp_camera_fb_return(fb); if(!s){ dl_matrix3du_free(image_matrix); Serial.println("to rgb888 failed"); httpd_resp_send_500(req); return ESP_FAIL; } box_array_t *net_boxes = face_detect(image_matrix, &mtmn_config); if (net_boxes){ detected = true; if(recognition_enabled){ face_id = run_face_recognition(image_matrix, net_boxes); } draw_face_boxes(image_matrix, net_boxes, face_id); free(net_boxes->score); free(net_boxes->box); free(net_boxes->landmark); free(net_boxes); } jpg_chunking_t jchunk = {req, 0}; s = fmt2jpg_cb(out_buf, out_len, out_width, out_height, PIXFORMAT_RGB888, 90, jpg_encode_stream, &jchunk); dl_matrix3du_free(image_matrix); if(!s){ Serial.println("JPEG compression failed"); return ESP_FAIL; } int64_t fr_end = esp_timer_get_time(); Serial.printf("FACE: %uB %ums %s%d\n", (uint32_t)(jchunk.len), (uint32_t)((fr_end - fr_start)/1000), detected?"DETECTED ":"", face_id); return res; } static esp_err_t stream_handler(httpd_req_t *req){ camera_fb_t * fb = NULL; esp_err_t res = ESP_OK; size_t _jpg_buf_len = 0; uint8_t * _jpg_buf = NULL; char * part_buf[64]; dl_matrix3du_t *image_matrix = NULL; bool detected = false; int face_id = 0; int64_t fr_start = 0; int64_t fr_ready = 0; int64_t fr_face = 0; int64_t fr_recognize = 0; int64_t fr_encode = 0; static int64_t last_frame = 0; if(!last_frame) { last_frame = esp_timer_get_time(); } res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); if(res != ESP_OK){ return res; } httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); while(true){ detected = false; face_id = 0; fb = esp_camera_fb_get(); if (!fb) { Serial.println("Camera capture failed"); res = ESP_FAIL; } else { fr_start = esp_timer_get_time(); fr_ready = fr_start; fr_face = fr_start; fr_encode = fr_start; fr_recognize = fr_start; if(!detection_enabled || fb->width > 400){ if(fb->format != PIXFORMAT_JPEG){ bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); esp_camera_fb_return(fb); fb = NULL; if(!jpeg_converted){ Serial.println("JPEG compression failed"); res = ESP_FAIL; } } else { _jpg_buf_len = fb->len; _jpg_buf = fb->buf; } } else { image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3); if (!image_matrix) { Serial.println("dl_matrix3du_alloc failed"); res = ESP_FAIL; } else { if(!fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item)){ Serial.println("fmt2rgb888 failed"); res = ESP_FAIL; } else { fr_ready = esp_timer_get_time(); box_array_t *net_boxes = NULL; if(detection_enabled){ net_boxes = face_detect(image_matrix, &mtmn_config); } fr_face = esp_timer_get_time(); fr_recognize = fr_face; if (net_boxes || fb->format != PIXFORMAT_JPEG){ if(net_boxes){ detected = true; if(recognition_enabled){ face_id = run_face_recognition(image_matrix, net_boxes); } fr_recognize = esp_timer_get_time(); draw_face_boxes(image_matrix, net_boxes, face_id); free(net_boxes->score); free(net_boxes->box); free(net_boxes->landmark); free(net_boxes); } if(!fmt2jpg(image_matrix->item, fb->width*fb->height*3, fb->width, fb->height, PIXFORMAT_RGB888, 90, &_jpg_buf, &_jpg_buf_len)){ Serial.println("fmt2jpg failed"); res = ESP_FAIL; } esp_camera_fb_return(fb); fb = NULL; } else { _jpg_buf = fb->buf; _jpg_buf_len = fb->len; } fr_encode = esp_timer_get_time(); } dl_matrix3du_free(image_matrix); } } } if(res == ESP_OK){ res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); } if(res == ESP_OK){ size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); } if(res == ESP_OK){ res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); } if(fb){ esp_camera_fb_return(fb); fb = NULL; _jpg_buf = NULL; } else if(_jpg_buf){ free(_jpg_buf); _jpg_buf = NULL; } if(res != ESP_OK){ break; } int64_t fr_end = esp_timer_get_time(); int64_t ready_time = (fr_ready - fr_start)/1000; int64_t face_time = (fr_face - fr_ready)/1000; int64_t recognize_time = (fr_recognize - fr_face)/1000; int64_t encode_time = (fr_encode - fr_recognize)/1000; int64_t process_time = (fr_encode - fr_start)/1000; int64_t frame_time = fr_end - last_frame; last_frame = fr_end; frame_time /= 1000; uint32_t avg_frame_time = ra_filter_run(&ra_filter, frame_time); Serial.printf("MJPG: %uB %ums (%.1ffps), AVG: %ums (%.1ffps), %u+%u+%u+%u=%u %s%d\n", (uint32_t)(_jpg_buf_len), (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time, avg_frame_time, 1000.0 / avg_frame_time, (uint32_t)ready_time, (uint32_t)face_time, (uint32_t)recognize_time, (uint32_t)encode_time, (uint32_t)process_time, (detected)?"DETECTED ":"", face_id ); } last_frame = 0; return res; } static esp_err_t cmd_handler(httpd_req_t *req){ char* buf; size_t buf_len; char variable[32] = {0,}; char value[32] = {0,}; buf_len = httpd_req_get_url_query_len(req) + 1; if (buf_len > 1) { buf = (char*)malloc(buf_len); if(!buf){ httpd_resp_send_500(req); return ESP_FAIL; } if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) { if (httpd_query_key_value(buf, "var", variable, sizeof(variable)) == ESP_OK && httpd_query_key_value(buf, "val", value, sizeof(value)) == ESP_OK) { } else { free(buf); httpd_resp_send_404(req); return ESP_FAIL; } } else { free(buf); httpd_resp_send_404(req); return ESP_FAIL; } free(buf); } else { httpd_resp_send_404(req); return ESP_FAIL; } int val = atoi(value); sensor_t * s = esp_camera_sensor_get(); int res = 0; if(!strcmp(variable, "framesize")) { if(s->pixformat == PIXFORMAT_JPEG) res = s->set_framesize(s, (framesize_t)val); } else if(!strcmp(variable, "quality")) res = s->set_quality(s, val); else if(!strcmp(variable, "contrast")) res = s->set_contrast(s, val); else if(!strcmp(variable, "brightness")) res = s->set_brightness(s, val); else if(!strcmp(variable, "saturation")) res = s->set_saturation(s, val); else if(!strcmp(variable, "gainceiling")) res = s->set_gainceiling(s, (gainceiling_t)val); else if(!strcmp(variable, "colorbar")) res = s->set_colorbar(s, val); else if(!strcmp(variable, "awb")) res = s->set_whitebal(s, val); else if(!strcmp(variable, "agc")) res = s->set_gain_ctrl(s, val); else if(!strcmp(variable, "aec")) res = s->set_exposure_ctrl(s, val); else if(!strcmp(variable, "hmirror")) res = s->set_hmirror(s, val); else if(!strcmp(variable, "vflip")) res = s->set_vflip(s, val); else if(!strcmp(variable, "awb_gain")) res = s->set_awb_gain(s, val); else if(!strcmp(variable, "agc_gain")) res = s->set_agc_gain(s, val); else if(!strcmp(variable, "aec_value")) res = s->set_aec_value(s, val); else if(!strcmp(variable, "aec2")) res = s->set_aec2(s, val); else if(!strcmp(variable, "dcw")) res = s->set_dcw(s, val); else if(!strcmp(variable, "bpc")) res = s->set_bpc(s, val); else if(!strcmp(variable, "wpc")) res = s->set_wpc(s, val); else if(!strcmp(variable, "raw_gma")) res = s->set_raw_gma(s, val); else if(!strcmp(variable, "lenc")) res = s->set_lenc(s, val); else if(!strcmp(variable, "special_effect")) res = s->set_special_effect(s, val); else if(!strcmp(variable, "wb_mode")) res = s->set_wb_mode(s, val); else if(!strcmp(variable, "ae_level")) res = s->set_ae_level(s, val); else if(!strcmp(variable, "face_detect")) { detection_enabled = val; if(!detection_enabled) { recognition_enabled = 0; } } else if(!strcmp(variable, "face_enroll")) is_enrolling = val; else if(!strcmp(variable, "face_recognize")) { recognition_enabled = val; if(recognition_enabled){ detection_enabled = val; } } else { res = -1; } if(res){ return httpd_resp_send_500(req); } httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); return httpd_resp_send(req, NULL, 0); } static esp_err_t status_handler(httpd_req_t *req){ static char json_response[1024]; sensor_t * s = esp_camera_sensor_get(); char * p = json_response; *p++ = '{'; p+=sprintf(p, "\"framesize\":%u,", s->status.framesize); p+=sprintf(p, "\"quality\":%u,", s->status.quality); p+=sprintf(p, "\"brightness\":%d,", s->status.brightness); p+=sprintf(p, "\"contrast\":%d,", s->status.contrast); p+=sprintf(p, "\"saturation\":%d,", s->status.saturation); p+=sprintf(p, "\"sharpness\":%d,", s->status.sharpness); p+=sprintf(p, "\"special_effect\":%u,", s->status.special_effect); p+=sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode); p+=sprintf(p, "\"awb\":%u,", s->status.awb); p+=sprintf(p, "\"awb_gain\":%u,", s->status.awb_gain); p+=sprintf(p, "\"aec\":%u,", s->status.aec); p+=sprintf(p, "\"aec2\":%u,", s->status.aec2); p+=sprintf(p, "\"ae_level\":%d,", s->status.ae_level); p+=sprintf(p, "\"aec_value\":%u,", s->status.aec_value); p+=sprintf(p, "\"agc\":%u,", s->status.agc); p+=sprintf(p, "\"agc_gain\":%u,", s->status.agc_gain); p+=sprintf(p, "\"gainceiling\":%u,", s->status.gainceiling); p+=sprintf(p, "\"bpc\":%u,", s->status.bpc); p+=sprintf(p, "\"wpc\":%u,", s->status.wpc); p+=sprintf(p, "\"raw_gma\":%u,", s->status.raw_gma); p+=sprintf(p, "\"lenc\":%u,", s->status.lenc); p+=sprintf(p, "\"vflip\":%u,", s->status.vflip); p+=sprintf(p, "\"hmirror\":%u,", s->status.hmirror); p+=sprintf(p, "\"dcw\":%u,", s->status.dcw); p+=sprintf(p, "\"colorbar\":%u,", s->status.colorbar); p+=sprintf(p, "\"face_detect\":%u,", detection_enabled); p+=sprintf(p, "\"face_enroll\":%u,", is_enrolling); p+=sprintf(p, "\"face_recognize\":%u", recognition_enabled); *p++ = '}'; *p++ = 0; httpd_resp_set_type(req, "application/json"); httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); return httpd_resp_send(req, json_response, strlen(json_response)); } static esp_err_t index_handler(httpd_req_t *req){ httpd_resp_set_type(req, "text/html"); httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); sensor_t * s = esp_camera_sensor_get(); if (s->id.PID == OV3660_PID) { return httpd_resp_send(req, (const char *)index_ov3660_html_gz, index_ov3660_html_gz_len); } return httpd_resp_send(req, (const char *)index_ov2640_html_gz, index_ov2640_html_gz_len); } static esp_err_t gpio12On_handler(httpd_req_t *req){ Serial.println("ON, 12.port HIGH"); digitalWrite(12, HIGH); return httpd_resp_send(req, NULL, 0); } static esp_err_t gpio12Off_handler(httpd_req_t *req){ Serial.println("OFF, 12.port LOW"); digitalWrite(12, LOW); return httpd_resp_send(req, NULL, 0); } static esp_err_t gpio13On_handler(httpd_req_t *req){ Serial.println("ON, 13.port HIGH"); digitalWrite(13, HIGH); return httpd_resp_send(req, NULL, 0); } static esp_err_t gpio13Off_handler(httpd_req_t *req){ Serial.println("OF, 13.port LOW"); digitalWrite(13, LOW); return httpd_resp_send(req, NULL, 0); } void startCameraServer(){ httpd_config_t config = HTTPD_DEFAULT_CONFIG(); httpd_uri_t index_uri = { .uri = "/", .method = HTTP_GET, .handler = index_handler, .user_ctx = NULL }; httpd_uri_t status_uri = { .uri = "/status", .method = HTTP_GET, .handler = status_handler, .user_ctx = NULL }; httpd_uri_t cmd_uri = { .uri = "/control", .method = HTTP_GET, .handler = cmd_handler, .user_ctx = NULL }; httpd_uri_t capture_uri = { .uri = "/capture", .method = HTTP_GET, .handler = capture_handler, .user_ctx = NULL }; httpd_uri_t stream_uri = { .uri = "/stream", .method = HTTP_GET, .handler = stream_handler, .user_ctx = NULL }; httpd_uri_t gpio12On_uri = { .uri = "/gpio12On", .method = HTTP_GET, .handler = gpio12On_handler, .user_ctx = NULL }; httpd_uri_t gpio12Off_uri = { .uri = "/gpio12Off", .method = HTTP_GET, .handler = gpio12Off_handler, .user_ctx = NULL }; httpd_uri_t gpio13On_uri = { .uri = "/gpio13On", .method = HTTP_GET, .handler = gpio13On_handler, .user_ctx = NULL }; httpd_uri_t gpio13Off_uri = { .uri = "/gpio13Off", .method = HTTP_GET, .handler = gpio13Off_handler, .user_ctx = NULL }; ra_filter_init(&ra_filter, 20); mtmn_config.type = FAST; mtmn_config.min_face = 80; mtmn_config.pyramid = 0.707; mtmn_config.pyramid_times = 4; mtmn_config.p_threshold.score = 0.6; mtmn_config.p_threshold.nms = 0.7; mtmn_config.p_threshold.candidate_number = 20; mtmn_config.r_threshold.score = 0.7; mtmn_config.r_threshold.nms = 0.7; mtmn_config.r_threshold.candidate_number = 10; mtmn_config.o_threshold.score = 0.7; mtmn_config.o_threshold.nms = 0.7; mtmn_config.o_threshold.candidate_number = 1; face_id_init(&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES); Serial.printf("Starting web server on port: '%d'\n", config.server_port); if (httpd_start(&camera_httpd, &config) == ESP_OK) { httpd_register_uri_handler(camera_httpd, &index_uri); httpd_register_uri_handler(camera_httpd, &cmd_uri); httpd_register_uri_handler(camera_httpd, &status_uri); httpd_register_uri_handler(camera_httpd, &capture_uri); } config.server_port += 1; config.ctrl_port += 1; Serial.printf("Starting stream server on port: '%d'\n", config.server_port); if (httpd_start(&stream_httpd, &config) == ESP_OK) { httpd_register_uri_handler(stream_httpd, &stream_uri); httpd_register_uri_handler(stream_httpd, &gpio12On_uri); httpd_register_uri_handler(stream_httpd, &gpio12Off_uri); httpd_register_uri_handler(stream_httpd, &gpio13On_uri); httpd_register_uri_handler(stream_httpd, &gpio13Off_uri); } }
mDNS on arduino: avahi mDNS daemon returning strange "Received conflicting record [...]. Resetting our record."
I'm trying to implement a lightweight mDNS announcer for arduino. It should announce the "apple midi rtp" service. Now the good part is that I can ping it my name (mymdnstest.local) most of the time and sometimes it shows up in the output of "avahi-browse -a". Always the avahi-daemon shows in the systemd logging: Received conflicting record [_apple-midi._udp.local IN PTR mymdnstest._apple-midi._udp.local ; ttl=120]. Resetting our record.". tcpdump shows: 22:12:00.691720 wlo1 M IP (tos 0x0, ttl 2, id 969, offset 0, flags [none], proto UDP (17), length 199) 192.168.65.215.5353 > 224.0.0.251.5353: [udp sum ok] 0*- [0q] 3/0/0 _apple-midi._udp.local. (Cache flush) [2m] PTR mymdnstest._apple-midi._udp.local., _apple-midi._udp.local. (Cache flush) [2m] SRV mymdnstest.local.:5004 0 0, mymdnstest.local. (Cache flush) [2m] A 192.168.65.215 (171) What can it be that these errors are seen and that it behaves so randomly? #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <WiFiUdp.h> char ssid[] = " my ssid "; char pass[] = " password for my ssid "; WiFiUDP udp; const IPAddress tgt_ip { 224, 0, 0, 251 }; constexpr int tgt_port = 5353; constexpr char name[] = "mymdnstest"; constexpr uint16_t port = 5004; void update_mdns() { static uint32_t last_msg = 0; uint32_t now = millis(); if (last_msg == 0 || now - last_msg >= 750) { last_msg = now; static bool state = true; digitalWrite(D0, state); // blink led state = !state; uint8_t response[256]; uint16_t ro = 0; response[ro++] = 0x00; // transaction id response[ro++] = 0x00; response[ro++] = 0x84; // standard query response, no error response[ro++] = 0x00; response[ro++] = 0x00; // 0 questions response[ro++] = 0x00; response[ro++] = 0x00; // 3 answers response[ro++] = 0x03; response[ro++] = 0x00; // 0 authority rr response[ro++] = 0x00; response[ro++] = 0x00; // 0 additional rr response[ro++] = 0x00; // PTR record constexpr char applemidi[] = "_apple-midi"; constexpr char udp_[] = "_udp"; constexpr char local[] = "local"; response[ro++] = strlen(applemidi); ro += sprintf((char *)&response[ro], "%s", applemidi); // name itself response[ro++] = strlen(udp_); ro += sprintf((char *)&response[ro], "%s", udp_); // name itself response[ro++] = strlen(local); ro += sprintf((char *)&response[ro], "%s", local); // name itself response[ro++] = 0x00; response[ro++] = 0x00; // PTR (12) response[ro++] = 0x0c; response[ro++] = 0x80; // cache flush & class: in response[ro++] = 0x01; response[ro++] = 0x00; // ttl 2 minutes response[ro++] = 0x00; response[ro++] = 0x00; response[ro++] = 0x78; uint16_t ptr_data_len = 1 + strlen(name) + 1 + strlen(applemidi) + 1 + strlen(udp_) + 1 + strlen(local) + 1; response[ro++] = ptr_data_len >> 8; response[ro++] = ptr_data_len; response[ro++] = strlen(name); ro += sprintf((char *)&response[ro], "%s", name); // name itself response[ro++] = strlen(applemidi); ro += sprintf((char *)&response[ro], "%s", applemidi); // name itself response[ro++] = strlen(udp_); ro += sprintf((char *)&response[ro], "%s", udp_); // name itself response[ro++] = strlen(local); ro += sprintf((char *)&response[ro], "%s", local); // name itself response[ro++] = 0x00; // SRV apple midi record response[ro++] = strlen(applemidi); // length of name ro += sprintf((char *)&response[ro], "%s", applemidi); // name itself response[ro++] = strlen(udp_); ro += sprintf((char *)&response[ro], "%s", udp_); // name itself response[ro++] = strlen(local); ro += sprintf((char *)&response[ro], "%s", local); // name itself response[ro++] = 0; // string delimiter response[ro++] = 0x00; // type 33 SRV (server selection) response[ro++] = 0x21; response[ro++] = 0x80; // class (cache flush: True, class: in) response[ro++] = 0x01; response[ro++] = 0x00; // ttl 2 minutes response[ro++] = 0x00; response[ro++] = 0x00; response[ro++] = 0x78; uint16_t srv_data_len = 2 + 2 + 2 + 1 + strlen(name) + 1 + strlen(local) + 1; response[ro++] = srv_data_len >> 8; // data len response[ro++] = srv_data_len; response[ro++] = 0x00; // priority response[ro++] = 0x00; response[ro++] = 0x00; // weight response[ro++] = 0x00; response[ro++] = port >> 8; // port on which the apple thing listens response[ro++] = port; response[ro++] = strlen(name); // length of name ro += sprintf((char *)&response[ro], "%s", name); // name itself response[ro++] = strlen(local); ro += sprintf((char *)&response[ro], "%s", local); // name itself response[ro++] = 0x00; // A record for the hostname to the ip-address response[ro++] = strlen(name); // length of name ro += sprintf((char *)&response[ro], "%s", name); // name itself response[ro++] = strlen(local); // length of "local" ro += sprintf((char *)&response[ro], local); response[ro++] = 0; // string delimiter response[ro++] = 0x00; // type 0001 (A) response[ro++] = 0x01; response[ro++] = 0x80; // class (cache flush: True, class: in) response[ro++] = 0x01; response[ro++] = 0x00; // ttl 2 minutes response[ro++] = 0x00; response[ro++] = 0x00; response[ro++] = 0x78; response[ro++] = 0x00; // length of address response[ro++] = 0x04; response[ro++] = WiFi.localIP()[0]; response[ro++] = WiFi.localIP()[1]; response[ro++] = WiFi.localIP()[2]; response[ro++] = WiFi.localIP()[3]; udp.beginPacketMulticast(tgt_ip, tgt_port, WiFi.localIP(), 2); udp.write(response, ro); udp.endPacket(); } } void setup() { Serial.begin(115200); Serial.println(F("Go!")); pinMode(D0, OUTPUT); WiFi.hostname(name); WiFi.begin(ssid, pass); static bool state = true; while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print(F(".")); digitalWrite(D0, state); state = !state; } digitalWrite(D0, false); Serial.println(F("")); Serial.print("IP address:\t"); IPAddress myIP = WiFi.localIP(); Serial.println(myIP); udp.beginMulticast(WiFi.localIP(), tgt_ip, 5353); } void loop() { update_mdns(); } pcap: https://vps001.vanheusden.com/~folkert/mdns.pcap
the flags of each RR were incorrect. only A and SRV should have clear cache the hostname was missing from the SRV record There is still a problem with it: rtpmidid signals a time-out when resolving the hostname but that doesn't fit this question.
Can someone give me the code for esp32 cam in order to upload the captured image to a local server using http post method?
I want to capture some moment using esp32 cam (by AI Thinker) and this captured photo should upload to a local server using HTTP post method. I am completely new to HTTP request. I want the arduino code. Here is my code, it never connects to server. I tried by removing the client.connect function but it still not works. #include<WiFi.h> #include<WiFiClientSecure.h> #include "esp_camera.h" #include "esp_timer.h" #include "img_converters.h" #include "Arduino.h" #include "fb_gfx.h" #include "fd_forward.h" #include "fr_forward.h" #include "FS.h" #include "SD_MMC.h" #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include "driver/rtc_io.h" #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 const char* ssid = "unknown"; const char* password = "unknown"; const char* host = "192.168.1.249"; const int Port = 5000; const char* boundry = "dgbfhfh"; WiFiClientSecure client; void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); Serial.begin(115200); pinMode(4,OUTPUT); Serial.printf("Connecting to the Wifi [%s]...\r\n", ssid); WiFi.begin(ssid,password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected"); camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; if(psramFound()) { config.frame_size = FRAMESIZE_QVGA; // FRAMESIZE_ +QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_QVGA; config.jpeg_quality = 12; config.fb_count = 1; } // Initialise Camera esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } sendPhotoToServer(); } void sendPhotoToServer() { Serial.printf("Connecting to %s:%d... ", host,Port); if (!client.connect(host,Port)) { Serial.println("Failure in connection with the server"); return; } sendDataToServer(); } void sendDataToServer() { String start_request = ""; String end_request = ""; start_request = start_request + "--" + boundry + "\r\n"; start_request = start_request + "Content-Disposition: form- data; name=\"image\"\r\n"; start_request = start_request + "Content-Type: image/jpeg\r\n"; start_request = start_request + "\r\n"; end_request = end_request + "\r\n"; end_request = end_request + "--" + boundry + "--" + "\r\n"; /************************************************/ digitalWrite(4,HIGH); camera_fb_t * fb = NULL; // Take Picture with Camera fb = esp_camera_fb_get(); if(!fb) { Serial.println("Camera capture failed"); return; } digitalWrite(4,LOW); delay(1000); /************************************************/ int contentLength = (int)fb->len + start_request.length() + end_request.length(); String headers = String("POST /image-upload HTTP/1.1\r\n"); headers = headers + "Host: " + host + "\r\n"; headers = headers + "User-Agent: ESP8266" + "\r\n"; headers = headers + "Accept: */*\r\n"; headers = headers + "Content-Type: multipart/form-data; boundary=" + boundry + "\r\n"; headers = headers + "Content-Length: " + contentLength + "\r\n"; headers = headers + "\r\n"; headers = headers + "\r\n"; Serial.println(); Serial.println("Sending data to Server..."); Serial.print(headers); client.print(headers); client.flush(); Serial.print(start_request); client.print(start_request); client.flush(); /*****************************************************/ int iteration = fb->len / 1024; for(int i=0; i<iteration; i++) { client.write(fb->buf,1024); fb->buf += 1024; client.flush(); } size_t remain = fb->len % 1024; client.write(fb->buf,remain); client.flush(); /****************************************************/ Serial.print(end_request); client.print(end_request); client.flush(); esp_camera_fb_return(fb); } void loop() { }
Hello there are quite a lot of examples about how to do it online. Check out this project: https://github.com/martinberlin/FS32/blob/master/src/FasarekFS2.ino#L433 Basically just like you do in the web, you need to create the right headers in the ESP32: String boundary = "_cam_"; String end_request = "\n--"+boundary+"--\n"; String start_request = start_request + "\n--"+boundary+"\n" + "Content-Disposition: form-data; name=\"upload\"; filename=\"CAM.JPG\"\n" + "Content-Transfer-Encoding: binary\n\n"; WiFiClient client; client.println("POST "+String(upload_path)+" HTTP/1.1"); client.println("Host: "+String(upload_host)); client.println("Content-Type: multipart/form-data; boundary="+boundary); client.print("Content-Length: "); client.println(full_length); client.println(); client.print(start_request); Then you should read the image in a Buffer and send it to the client. Ending with a: client.println(end_request); I know is quite a raw example. But it's the way I got it to work in different projects.
Here is your modified code. It is working !!! :D #include<WiFiClientSecure.h> #include "esp_camera.h" #include "esp_timer.h" #include "img_converters.h" #include "Arduino.h" #include "fb_gfx.h" #include "fd_forward.h" #include "fr_forward.h" #include "FS.h" #include "SD_MMC.h" #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include "driver/rtc_io.h" #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 const char* ssid = "***"; const char* password = "****"; const char* host = "192.168.3.19"; const int Port = 4567; const char* boundry = "dgbfhfh"; WiFiClientSecure client; void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); Serial.begin(115200); pinMode(4,OUTPUT); Serial.printf("Connecting to the Wifi [%s]...\r\n", ssid); WiFi.begin(ssid,password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected"); camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; if(psramFound()) { config.frame_size = FRAMESIZE_SXGA; // FRAMESIZE_ +QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_VGA; config.jpeg_quality = 12; config.fb_count = 1; } // Initialise Camera esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } sendPhotoToServer(); } void sendPhotoToServer() { Serial.printf("Connecting to %s:%d... ", host,Port); if (!client.connect(host,Port)) { Serial.println("Failure in connection with the server"); return; } sendDataToServer(); } void sendDataToServer() { String start_request = ""; String end_request = ""; start_request = start_request + "--" + boundry + "\r\n"; start_request = start_request + "Content-Disposition: form-data; name=\"file\"; filename=\"CAM.jpg\"\r\n"; start_request = start_request + "Content-Type: image/jpg\r\n"; start_request = start_request + "\r\n"; end_request = end_request + "\r\n"; end_request = end_request + "--" + boundry + "--" + "\r\n"; /************************************************/ digitalWrite(4,HIGH); camera_fb_t * fb = NULL; // Take Picture with Camera fb = esp_camera_fb_get(); if(!fb) { Serial.println("Camera capture failed"); return; } digitalWrite(4,LOW); delay(1000); /************************************************/ int contentLength = (int)fb->len + start_request.length() + end_request.length(); String headers = String("POST https://192.168.3.19:4567/api/upload HTTP/1.1\r\n"); headers = headers + "Host: " + host + "\r\n"; headers = headers + "User-Agent: ESP32" + "\r\n"; headers = headers + "Accept: */*\r\n"; headers = headers + "Content-Type: multipart/form-data; boundary=" + boundry + "\r\n"; headers = headers + "Content-Length: " + contentLength + "\r\n"; headers = headers + "\r\n"; headers = headers + "\r\n"; Serial.println(); Serial.println("Sending data to Server..."); Serial.print(headers); client.print(headers); client.flush(); Serial.print(start_request); client.print(start_request); client.flush(); /*****************************************************/ int iteration = fb->len / 1024; for(int i=0; i<iteration; i++) { client.write(fb->buf,1024); fb->buf += 1024; client.flush(); } size_t remain = fb->len % 1024; client.write(fb->buf,remain); client.flush(); /****************************************************/ Serial.print(end_request); client.print(end_request); client.flush(); esp_camera_fb_return(fb); } void loop() { } And backend method from Spark Java. Dont forget to make your spark server HTTPS/SSL !!! http://sparkjava.com/documentation#examples-and-faq public class Main { public static void main(String[] args) { secure("deploy/keystore.jks", "password", null, null); File uploadDir = new File("upload"); uploadDir.mkdir(); // create the upload directory if it doesn't exist post("/api/upload", (req, res) -> { req.attribute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement(uploadDir.getPath())); Part filePart = req.raw().getPart("file"); try (InputStream inputStream = filePart.getInputStream()) { OutputStream outputStream = new FileOutputStream(uploadDir + "/" + filePart.getSubmittedFileName()); IOUtils.copy(inputStream, outputStream); outputStream.close(); } return "File uploaded and saved."; }); } }
Error with Arduino/Processing serial communication
I am relatively new to both Arduino and Processing and I have been working on a code that utilizes serial communication between the two. My Arduino code is reading and printing values from a piezo sensor and then sending the values to Processing, which sketches certain shapes based on the values. The code has worked previously, but for some reason it is no longer working. Everything compiles, but when I run the Processing code the sketch window is empty and remains empty. A few times the "error, disabling serialEvent()" showed up, but I just unplugged my Arduino board, closed out the programs, and restarted everything. The error no longer shows up, but my Processing sketch is still not displaying on the screen. Can someone please let me know what is wrong with my code? I really appreciate the help. Arduino Code: int ledPin = 13; int knockSensor = A0; byte val = 0; int statePin = LOW; int THRESHOLD = 5; int sensorReading = 0; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { sensorReading = analogRead(knockSensor); if(sensorReading > 0) { Serial.println(sensorReading, DEC); } if (sensorReading != 0) Serial.println(sensorReading); delay(100); } Processing Code: import processing.serial.*; Serial port; int centerX = 550; int centerY = 400; float val; float ellipseX; float ellipseY; float ellipseW; float ellipseH; float ellipseXX; float ellipseYY; float ellipseWW; float ellipseHH; float lineX; float lineY; float lineXX; float lineYY; void setup(){ background(255); size(1100,800); frameRate(10); smooth(); String portname = "/dev/tty.usbmodem1411"; //String portname = Serial.list()[0]; port = new Serial(this, portname, 9600); println(Serial.list()); //port.bufferUntil('\n'); } void drawEllipse(float val) { if(val > 0 && val < 50) { ellipseX = random(540,560); ellipseY = random(390,410); ellipseW = val + 10; ellipseH = val + 10; stroke(0); fill(random(255), random(200,255)); } } void drawLines(float val) { if(val > 50 && val < 70) { lineX = random(500, 600); lineY = random(360, 440); lineXX = random(500, 600); lineYY = random(360, 440); stroke(0); } } void drawEllipse2(float val) { if(val > 70 && val < 120) { ellipseXX = random(460, 640); ellipseYY = random(330, 470); ellipseWW = val + random(20); ellipseHH = val + 10; stroke(0); fill(random(50, 100), random(50, 100), random(50, 100), random(220, 255)); } } void serialEvent(Serial port) { String inString = port.readStringUntil('\n'); if (inString != null) { val = Float.parseFloat(inString); } drawEllipse(val); drawLines(val); drawEllipse2(val); println(val); }
Maybe using Serial.write() will be better. So the code will look like this. Arduino Code: int ledPin = 13; int knockSensor = A0; byte val = 0; int statePin = LOW; int THRESHOLD = 5; int sensorReading = 0; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { sensorReading = analogRead(knockSensor); if(sensorReading > 0) { Serial.println(sensorReading, DEC); } if (sensorReading != 0) Serial.write(map(sensorReading, 0, 1023, 0, 255)); delay(100); } Processing Code: import processing.serial.*; Serial port; int centerX = 550; int centerY = 400; float val; float ellipseX; float ellipseY; float ellipseW; float ellipseH; float ellipseXX; float ellipseYY; float ellipseWW; float ellipseHH; float lineX; float lineY; float lineXX; float lineYY; void setup(){ background(255); size(1100,800); frameRate(10); smooth(); String portname = "/dev/tty.usbmodem1411"; //String portname = Serial.list()[0]; port = new Serial(this, portname, 9600); println(Serial.list()); //port.bufferUntil('\n'); } void drawEllipse(float val) { if(val > 0 && val < 50) { ellipseX = random(540,560); ellipseY = random(390,410); ellipseW = val + 10; ellipseH = val + 10; stroke(0); fill(random(255), random(200,255)); } } void drawLines(float val) { if(val > 50 && val < 70) { lineX = random(500, 600); lineY = random(360, 440); lineXX = random(500, 600); lineYY = random(360, 440); stroke(0); } } void drawEllipse2(float val) { if(val > 70 && val < 120) { ellipseXX = random(460, 640); ellipseYY = random(330, 470); ellipseWW = val + random(20); ellipseHH = val + 10; stroke(0); fill(random(50, 100), random(50, 100), random(50, 100), random(220, 255)); } } void serialEvent(Serial port) { if (0 < port.available()) { val = map(port.read(), 0, 255, 0, 1023); } if (val > 0) { drawEllipse(val); drawLines(val); drawEllipse2(val); println(val); } }