// Pin settings for I2C communication
#define SCL_PIN 5 // SCL (clock) pin
#define SCL_PORT PORTC
#define SDA_PIN 4 // SDA (data) pin
#define SDA_PORT PORTC
#define I2C_TIMEOUT 100 // Timeout setting (100ms)
#include <SoftI2CMaster.h> // I2C communication library
// Sensor address (default)
#define SENSOR_ADDRESS 224 // Default address of the sensor to use
void setup() {
// Start serial communication
Serial.begin(9600);
i2c_init(); // Initialize I2C communication
Serial.println("Setup complete!");
}
void loop() {
// Read distance from the sensor
read_the_sensor_example();
delay(1000); // Wait 1 second before reading again
}
void read_the_sensor_example(){
boolean error = 0; // Create a bit to check for catch errors as needed.
int range;
// Take a range reading at the default address of 224
error = start_sensor(224); // Start the sensor and collect any error codes.
if (!error){ // If you had an error starting the sensor there is little point in reading it
delay(100);
range = read_sensor(224); // Reading the sensor will return an integer value -- if this value is 0 there was
Serial.print("R:");Serial.println(range);
}
}
int read_sensor(byte bit8address){
boolean errorlevel = 0;
int range = 0;
byte range_highbyte = 0;
byte range_lowbyte = 0;
bit8address = bit8address | B00000001; // Do a bitwise 'or' operation to force the last bit to be 'one' -- we are
errorlevel = !i2c_start(bit8address) | errorlevel;
range_highbyte = i2c_read(0); // Read a byte and send an ACK (acknowledge)
range_lowbyte = i2c_read(1); // Read a byte and send a NACK to terminate the transmission
i2c_stop();
range = (range_highbyte * 256) + range_lowbyte; // Compile the range integer from the two bytes received.
if(errorlevel){
return 0;
}
else{
return range;
}
}
boolean start_sensor(byte bit8address){
boolean errorlevel = 0;
bit8address = bit8address & B11111110; // Do a bitwise 'and' operation to force the last bit to be
errorlevel = !i2c_start(bit8address) | errorlevel; // Run i2c_start(address) while doing so, collect any errors
errorlevel = !i2c_write(81) | errorlevel; // Send the 'take range reading' command. (notice how the
i2c_stop();
return errorlevel;
}
OK, so you are sure that the device is wired correctly and you e seen it on the bus using code you did not write it mess with, a scanner or test program of some kind?
Also, why are you using software I2C? It can't be because you have other planz for A4 and A5, the hardware I2C pins.
Asking for me (because my friend is shy), is the "half/double" address the silkscreen on the board/docs or the scanned address, and how is it interpreted (when should I know to use another value than the result of the scan). I don't even know if I am asking the right question.
WOKWI: I played with I2C addresses on Wokwi and fit a bunch of devices with the same address by giving them different "attrs": { "i2cAddress": "0x??"} in diagram.json. Two devices on Wokwi have the same address (LCD and IMU?) as a default.
Nice idea with the wokwi. When you specify that attribute, is it the number you needa use in constructors or begin() methods?
Did you try the scanner in wokwi? Does it find the device at that same number? I would except I'm at the beach on a tablet, I'm too lazy to fight with wokwi, especially anonymously as it would have to be.
I wish I could hang onto this, I have to "learn" it every time, obvsly I am not learning.