I am a complete Arduino neophyte so I need help from you pros!
I want to embellish my residential community’s shared water well system with the ability to remotely monitor the water level in its 1500-gallon storage tank.
I began with a waterproof ultrasonic sensor (JSN-SR04T) and an Arduino Uno (affectionately named ‘Tony’). The code I’m currently running on Tony perfectly reports the depth via the Arduino serial monitor.
But my desire is to interface Tony to an existing Particle Electron (embedded on an NCD-MCP23008 PCB/shield) via the I2C bus. This would allow the depth data to be remotely accessible via IoT using the Particle Cloud.
Specifically, I want to pass the contents of a float variable ‘gallons’ to the Electron (I need to report fractional gallons). I embellished Tony’s code with what on-line tutorials suggest are the proper commands and functions to enable I2C communications, but I have so far been unsuccessful in passing any data of any type from Tony to the Electron.
The Wire.write function will not accept a float variable or a String variable (the lack of String support begs the question: how can you ever pass anything but a number via I2C?), so for testing purposes I declared ‘gallons’ as a byte, as a long and then as an integer. In all cases the code compiled, but only zeros showed up on the other end (on the Electron).
I tried sending an actual string (not to be confused with a String variable); Wire.write accepted it, i.e. it compiled, but again nothing showed up in the Particle console.
Below is the latest iteration of my Arduino code. Note that I have been unable to figure out the difference between the Wire.onReceive(requestEvent) and Wire.onRequest(requestEvent) functions, so I've tried them both separately and together; no change.
Can any of you experts out there help me figure out what I’m doing wrong?
#include <Wire.h>
#include <stdlib.h>
/* Arduino example sketch to control a JSN-SR04T ultrasonic distance sensor with Arduino. No library needed. More info: https://www.makerguides.com */
// Define Trig and Echo pin:
#define trigPin 2
#define echoPin 3
// Define variables:
long duration;
float distance;
byte gallons;
byte requestEvent;
String depth;
void setup() {
// Define inputs and outputs
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Begin Serial communication at a baudrate of 9600:
Serial.begin(9600);
Wire.begin(8);
Wire.onReceive(requestEvent);
Wire.onRequest(requestEvent);
}
void loop() {
// Clear the trigPin by setting it LOW:
digitalWrite(trigPin, LOW);
delayMicroseconds(5);
// Trigger the sensor by setting the trigPin high for 10 microseconds:
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the echoPin. pulseIn() returns the duration (length of the pulse) in microseconds:
duration = pulseIn(echoPin, HIGH);
// Calculate the distance in cm:
distance = duration * 0.034 / 2;
// Convert to inches:
distance = distance * 0.393701;
// Adjust for error:
distance = distance * 1.037;
int i;
char buff[10];
String depth = "";
dtostrf(distance, 5, 2, buff); //5 is mininum width, 2 is precision
depth += buff;
// This formula is for testing only:
gallons = distance * 30;
// Print the distance to the water surface on the Serial Monitor:
Serial.print("Distance = ");
Serial.print(distance);
Serial.println(" in");
// Print the amount of water remaining on the Serial Monitor:
Serial.print("Depth = ");
Serial.print(gallons);
Serial.println(" gallons");
//The above code works flawlessly
void requestEvent(); //This Function is called when Master wants value from slave
{
// Wire.beginTransmission();
Wire.write(gallons);
// Wire.write(depth.c_str()); //Attempt to send a string
// Wire.endTransmission();
}
// Introduce a 5-second delay:
delay(5000);
}
For what it's worth, here's the code running on the Electron:
#include <Wire.h>
String data = String(10);
byte distance;
void setup() {
//Set the speed of the I2C port on the Photon and start it.
Serial.begin(9600);
Wire.begin();
}
void loop() {
Wire.beginTransmission(8);
Wire.requestFrom(8,1);
distance = Wire.read();
Wire.endTransmission();
Particle.publish ("Distance = ",String(distance),60, PRIVATE);
delay(10000);
}