From 249ec0f9483f3933e70002537d9b050d95569604 Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Mon, 27 May 2024 15:41:36 -0600 Subject: [PATCH 01/34] Adjusts example 1, adds additional function to ultrasonic class --- .../Example1_BasicReadings.ino | 11 +++++------ src/sfeQwiicUltrasonic.cpp | 19 +++++++++++++++++++ src/sfeQwiicUltrasonic.h | 5 +++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index 73cfe8b..c027ea1 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -22,7 +22,8 @@ void setup() while (myUltrasonic.begin(deviceAddress) == false) { Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); - delay(1000); + while(1) + ; } Serial.println("Ultrasonic sensor connected!"); @@ -30,15 +31,13 @@ void setup() void loop() { - // Get measurement from sensor. Note that the mesaured distance actually - // comes from the previous trigger, so measurements will be slightly delayed uint16_t distance = 0; - myUltrasonic.triggerAndRead(distance); + myUltrasonic.getDistance(distance); // Print measurement Serial.print("Distance (mm): "); Serial.println(distance); // Wait a bit - delay(100); -} \ No newline at end of file + delay(250); +} diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index d9b450b..2a2ab81 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -29,6 +29,25 @@ sfeTkError_t sfeQwiicUltrasonic::isConnected() return _theBus->ping(); } +sfeTkError_t sfeQwiicUltrasonic::getDistace(uint16_t &distance) +{ + size_t bytesRead = 0; + uint8_t rawData[2] = {0, 0}; + + // Attempt to read the distance + sfeTkError_t err = _theBus->readRegisterRegion(kQwiicUltrasonicRegisterTrigger, rawData, 2, bytesRead); + + // Check whether the read was successful + if (err != kSTkErrOk) + return err; + + // Store raw data + distance = (rawData[0] << 8) | rawData[1]; + + // Done! + return kSTkErrOk; +} + sfeTkError_t sfeQwiicUltrasonic::triggerAndRead(uint16_t &distance) { size_t bytesRead = 0; diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index 376a354..cd07511 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -31,6 +31,11 @@ class sfeQwiicUltrasonic /// @return 0 for succuss, negative for errors, positive for warnings sfeTkError_t isConnected(); + /// @brief Triggers a new measurement and reads the previous one + /// @param distance Distance in mm + /// @return 0 for succuss, negative for errors, positive for warnings + sfeTkError_t getDistace(uint16_t &distance); + /// @brief Triggers a new measurement and reads the previous one /// @param distance Distance in mm /// @return 0 for succuss, negative for errors, positive for warnings From 82ea547369779f2e6039130363477505f54e2e0d Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Tue, 28 May 2024 09:01:17 -0600 Subject: [PATCH 02/34] Adds some examples that will be rolled in shortly --- .../HC-SR04_UltrasonicSensorExample.ino | 331 ++++++++++++++++++ .../desktop.ini | 5 + Arduino/desktop.ini | 5 + .../example1_basic_distance.ino | 60 ++++ .../example2_basic_distance_trigger.ino | 72 ++++ .../example3_change_address.ino | 55 +++ src/sfeQwiicUltrasonic.cpp | 2 +- src/sfeQwiicUltrasonic.h | 2 +- 8 files changed, 530 insertions(+), 2 deletions(-) create mode 100644 Arduino/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino create mode 100644 Arduino/HC-SR04_UltrasonicSensorExample/desktop.ini create mode 100644 Arduino/desktop.ini create mode 100644 Arduino/example1_basic_distance/example1_basic_distance.ino create mode 100644 Arduino/example2_basic_distance_trigger/example2_basic_distance_trigger.ino create mode 100644 Arduino/example3_change_address/example3_change_address.ino diff --git a/Arduino/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino b/Arduino/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino new file mode 100644 index 0000000..7244c63 --- /dev/null +++ b/Arduino/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino @@ -0,0 +1,331 @@ +/** + * HC-SR04 Demo + * Demonstration of the HC-SR04 Ultrasonic Sensor + * Date: August 3, 2016 + * + * Description: + * Connect the ultrasonic sensor to the Arduino as per the + * hardware connections below. Run the sketch and open a serial + * monitor. The distance read from the sensor will be displayed + * in centimeters and inches. + * + * Hardware Connections: + * Arduino | HC-SR04 + * ------------------- + * 5V | VCC + * 7 | Trig + * 8 | Echo + * GND | GND + * + * License: + * Public Domain + */ +#include +#include +#include + +// Pins +const int TRIG_PIN = 7; +const int ECHO_PIN = 8; + +// Anything over 400 cm (23200 us pulse) is "out of range" +const unsigned int MAX_DIST = 23200; + +#define OLED_RESET 4 +Adafruit_SSD1306 display(OLED_RESET); + +#define NUMFLAKES 10 +#define XPOS 0 +#define YPOS 1 +#define DELTAY 2 + + +#define LOGO16_GLCD_HEIGHT 16 +#define LOGO16_GLCD_WIDTH 16 +static const unsigned char PROGMEM logo16_glcd_bmp[] = +{ B00000000, B11000000, + B00000001, B11000000, + B00000001, B11000000, + B00000011, B11100000, + B11110011, B11100000, + B11111110, B11111000, + B01111110, B11111111, + B00110011, B10011111, + B00011111, B11111100, + B00001101, B01110000, + B00011011, B10100000, + B00111111, B11100000, + B00111111, B11110000, + B01111100, B11110000, + B01110000, B01110000, + B00000000, B00110000 }; + +#if (SSD1306_LCDHEIGHT != 32) +#error("Height incorrect, please fix Adafruit_SSD1306.h!"); +#endif + +void setup() { + + // The Trigger pin will tell the sensor to range find + pinMode(TRIG_PIN, OUTPUT); + digitalWrite(TRIG_PIN, LOW); + + // We'll use the serial monitor to view the sensor output + Serial.begin(9600); + display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32) + display.clearDisplay(); +} + +void loop() { + + unsigned long t1; + unsigned long t2; + unsigned long pulse_width; + float cm; + float inches; + + // Hold the trigger pin high for at least 10 us + digitalWrite(TRIG_PIN, HIGH); + delayMicroseconds(50); + digitalWrite(TRIG_PIN, LOW); + + // Wait for pulse on echo pin + while ( digitalRead(ECHO_PIN) == 0 ); + + // Measure how long the echo pin was held high (pulse width) + // Note: the micros() counter will overflow after ~70 min + t1 = micros(); + while ( digitalRead(ECHO_PIN) == 1); + t2 = micros(); + pulse_width = t2 - t1; + + // Calculate distance in centimeters and inches. The constants + // are found in the datasheet, and calculated from the assumed speed + //of sound in air at sea level (~340 m/s). + cm = pulse_width / 58.0; + inches = pulse_width / 148.0; + + // Print out results + if ( pulse_width > MAX_DIST ) { + Serial.println("Out of range"); + } else { + Serial.print(cm); + Serial.print(" cm \t"); + Serial.print(inches); + Serial.println(" in"); + display.setTextSize(2); + display.setTextColor(WHITE); + display.setCursor(10,0); + display.clearDisplay(); + display.print(cm); + display.print("cm"); + display.display(); + delay(1); + + } + + // Wait at least 60ms before next measurement + delay(60); +} +void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) { + uint8_t icons[NUMFLAKES][3]; + + // initialize + for (uint8_t f=0; f< NUMFLAKES; f++) { + icons[f][XPOS] = random(display.width()); + icons[f][YPOS] = 0; + icons[f][DELTAY] = random(5) + 1; + + Serial.print("x: "); + Serial.print(icons[f][XPOS], DEC); + Serial.print(" y: "); + Serial.print(icons[f][YPOS], DEC); + Serial.print(" dy: "); + Serial.println(icons[f][DELTAY], DEC); + } + + while (1) { + // draw each icon + for (uint8_t f=0; f< NUMFLAKES; f++) { + display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE); + } + display.display(); + delay(200); + + // then erase it + move it + for (uint8_t f=0; f< NUMFLAKES; f++) { + display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK); + // move it + icons[f][YPOS] += icons[f][DELTAY]; + // if its gone, reinit + if (icons[f][YPOS] > display.height()) { + icons[f][XPOS] = random(display.width()); + icons[f][YPOS] = 0; + icons[f][DELTAY] = random(5) + 1; + } + } + } +} + + +void testdrawchar(void) { + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0,0); + + for (uint8_t i=0; i < 168; i++) { + if (i == '\n') continue; + display.write(i); + if ((i > 0) && (i % 21 == 0)) + display.println(); + } + display.display(); + delay(1); +} + +void testdrawcircle(void) { + for (int16_t i=0; i0; i-=5) { + display.fillTriangle(display.width()/2, display.height()/2-i, + display.width()/2-i, display.height()/2+i, + display.width()/2+i, display.height()/2+i, WHITE); + if (color == WHITE) color = BLACK; + else color = WHITE; + display.display(); + delay(1); + } +} + +void testdrawroundrect(void) { + for (int16_t i=0; i=0; i-=4) { + display.drawLine(0, display.height()-1, display.width()-1, i, WHITE); + display.display(); + delay(1); + } + delay(250); + + display.clearDisplay(); + for (int16_t i=display.width()-1; i>=0; i-=4) { + display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE); + display.display(); + delay(1); + } + for (int16_t i=display.height()-1; i>=0; i-=4) { + display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE); + display.display(); + delay(1); + } + delay(250); + + display.clearDisplay(); + for (int16_t i=0; i +const int ULTRA_ADDR = 0x2F; +const int BEGIN_MEASURE = 0x01; +int distance, distance_H, distance_L=0; + +void setup() { + + Wire.begin(); + + Serial.begin(115200); + Serial.println("Ultrasonic Distance Sensor - Example 1 Basic Distance Sensing."); + + Wire.beginTransmission(ULTRA_ADDR); + int error = Wire.endTransmission(); + if(error != 0){ + Serial.print("Could not communicate with the sensor, check that you have the correct address, or that your sensor is connected."); + while(1) + ; + } + + Serial.println("Ready to check distance."); + Serial.println("\n\n"); + delay(1000); +} + +void loop() { + + Wire.beginTransmission(ULTRA_ADDR); + Wire.write(BEGIN_MEASURE); + Wire.endTransmission(); + delay(20); + + Wire.requestFrom(ULTRA_ADDR, 2); + delay(20); + + while (Wire.available()) { + distance_H = Wire.read(); + distance_L = Wire.read(); + distance = distance_H << 8; + distance = distance|distance_L; + + Serial.print("Distance: "); + Serial.print(distance); + Serial.println("mm"); + + //Serial.print("Distance: "); + //Serial.print(distance / 10.0); + //Serial.println("cm", 2); + + //Serial.print("Distance: "); + //Serial.print(distance / 25.4); + //Serial.println("in", 2); + } + + Serial.println("\n"); + delay(500); +} diff --git a/Arduino/example2_basic_distance_trigger/example2_basic_distance_trigger.ino b/Arduino/example2_basic_distance_trigger/example2_basic_distance_trigger.ino new file mode 100644 index 0000000..9ffaee4 --- /dev/null +++ b/Arduino/example2_basic_distance_trigger/example2_basic_distance_trigger.ino @@ -0,0 +1,72 @@ +/*SparkFun Ultrasonic Distance Sensor Example 2 - Basic Distance Sensing using I2C and Trigger Pin +* and Echo pin. +*/ + +#include +const int ULTRA_ADDR = 0x2F; +const int BEGIN_MEASURE = 0x01; +int distanceRequested = 0; +int distance, distance_H, distance_L=0; +int triggerPin = 7; // Trigger Pin of Ultrasonic Sensor +int echoPin = 8; // Echo Pin of Ultrasonic Sensor + +void setup() { + + Wire.begin(); + + Serial.begin(115200); + Serial.println("Ultrasonic Distance Sensor - Example 1 Basic Distance Sensing."); + + pinMode(triggerPin, OUTPUT); + pinMode(echoPin, INPUT); + + Wire.beginTransmission(ULTRA_ADDR); + int error = Wire.endTransmission(); + if(error != 0){ + Serial.print("Could not communicate with the sensor, check that you have the correct address, or that your sensor is connected."); + while(1) + ; + } + + Serial.println("Ready to check distance."); + Serial.println("\n\n"); + delay(1000); +} + +void loop() { + + if(distanceRequested == 0) + { + digitalWrite(triggerPin, HIGH); + delay(5); + digitalWrite(triggerPin, LOW); + distanceRequested = 1; + } + + if (digitalRead(echoPin) == LOW) { + Wire.requestFrom(ULTRA_ADDR, 2); + delay(20); + + while (Wire.available()) { + distance_H = Wire.read(); + distance_L = Wire.read(); + distance = distance_H << 8; + distance = distance|distance_L; + + Serial.print("Distance: "); + Serial.print(distance); + Serial.println("mm"); + + //Serial.print("Distance: "); + //Serial.print(distance / 10.0); + //Serial.println("cm", 2); + + //Serial.print("Distance: "); + //Serial.print(distance / 25.4); + //Serial.println("in", 2); + Serial.println("\n"); + } + distanceRequested = 0; + } + delay(500); +} diff --git a/Arduino/example3_change_address/example3_change_address.ino b/Arduino/example3_change_address/example3_change_address.ino new file mode 100644 index 0000000..9038819 --- /dev/null +++ b/Arduino/example3_change_address/example3_change_address.ino @@ -0,0 +1,55 @@ +/*SparkFun Ultrasonic Distance Sensor Example 2 - Basic Distance Sensing using I2C and Trigger Pin +* and Echo pin. +*/ +#include +const int ULTRA_ADDR = 0x2F; +const int CHANGE_ADDR = 0x04; +const int NEW_ADDR = 0x1F; +int error; + +void setup() { + + Wire.begin(); + + Serial.begin(115200); + Serial.println("Ultrasonic Distance Sensor - Example 4 - Change Address"); + + Wire.beginTransmission(ULTRA_ADDR); + error = Wire.endTransmission(); + if(error != 0){ + Serial.print("Could not communicate with the sensor, check that you have the correct address, or that your sensor is connected."); + while(1) + ; + } + + Serial.println("Ready to change address."); + Serial.println("\n\n"); + delay(1000); +} + +void loop() { + + Serial.print("Changing address to: "); + Serial.println(NEW_ADDR, HEX); + Wire.beginTransmission(ULTRA_ADDR); + Wire.write(CHANGE_ADDR); + Wire.write(NEW_ADDR << 1); + Wire.endTransmission(); + + delay(1000); + + Wire.beginTransmission((NEW_ADDR); + error = Wire.endTransmission(); + if(error == 0){ + Serial.print("Address changed to: "); + Serial.println(NEW_ADDR, HEX); + while(1) + ; + } + else{ + Serial.println("Address did not change."); + Serial.println(error); + } + while(1) + ; +} diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 2a2ab81..e8fa641 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -48,7 +48,7 @@ sfeTkError_t sfeQwiicUltrasonic::getDistace(uint16_t &distance) return kSTkErrOk; } -sfeTkError_t sfeQwiicUltrasonic::triggerAndRead(uint16_t &distance) +sfeTkError_t sfeQwiicUltrasonic::getTriggeredDistance(uint16_t &distance) { size_t bytesRead = 0; uint8_t rawData[2] = {0, 0}; diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index cd07511..eaaa4ed 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -39,7 +39,7 @@ class sfeQwiicUltrasonic /// @brief Triggers a new measurement and reads the previous one /// @param distance Distance in mm /// @return 0 for succuss, negative for errors, positive for warnings - sfeTkError_t triggerAndRead(uint16_t &distance); + sfeTkError_t getTriggeredDistance(uint16_t &distance); /// @brief Changes the I2C address of the Qwiic Ultrasonic sensor /// @param address New address, must be in the range 0x20 to 0x2F From 8cf35e810b7015df342d191b219fc13b8ddcc26b Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Tue, 28 May 2024 09:05:53 -0600 Subject: [PATCH 03/34] Adds write to getDistance --- src/sfeQwiicUltrasonic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index e8fa641..ce81012 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -35,6 +35,7 @@ sfeTkError_t sfeQwiicUltrasonic::getDistace(uint16_t &distance) uint8_t rawData[2] = {0, 0}; // Attempt to read the distance + sfeTkError_t err = _theBus->write(kQwiicUltrasonicRegisterTrigger, rawData, 2, bytesRead); sfeTkError_t err = _theBus->readRegisterRegion(kQwiicUltrasonicRegisterTrigger, rawData, 2, bytesRead); // Check whether the read was successful From 64bff81ebafb6596c5be8239618e5d09a7e43282 Mon Sep 17 00:00:00 2001 From: santised Date: Tue, 28 May 2024 12:47:15 -0600 Subject: [PATCH 04/34] Adds I2C commands to relevant function --- .../Example1_BasicReadings.ino | 8 +++++++- src/sfeQwiicUltrasonic.cpp | 12 ++++++++---- src/sfeQwiicUltrasonic.h | 15 ++++++--------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index c027ea1..4da6cfe 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -14,7 +14,7 @@ void setup() { // Start serial Serial.begin(115200); - Serial.println("Qwiic Ultrasonic Example 1 - Basic Readings"); + Serial.println("Ultrasonic Distance Sensor Example 1 - Basic Distance Sensing"); Wire.begin(); @@ -38,6 +38,12 @@ void loop() Serial.print("Distance (mm): "); Serial.println(distance); + //Serial.println("Distance (cm): "); + //Serial.print((distance / 10.0), 2); + + //Serial.println("Distace (in): "); + //Serial.print((distance / 25.4), 2); + // Wait a bit delay(250); } diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index ce81012..530095b 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -33,10 +33,11 @@ sfeTkError_t sfeQwiicUltrasonic::getDistace(uint16_t &distance) { size_t bytesRead = 0; uint8_t rawData[2] = {0, 0}; + sfeTkError_t err; - // Attempt to read the distance - sfeTkError_t err = _theBus->write(kQwiicUltrasonicRegisterTrigger, rawData, 2, bytesRead); - sfeTkError_t err = _theBus->readRegisterRegion(kQwiicUltrasonicRegisterTrigger, rawData, 2, bytesRead); + _theBus->writeRegisterByte(theBus->address(), kUltrasonicDistanceReadCommand); + delay(10); + err = _theBus->readRegisterRegion(kQwiicUltrasonicRegisterTrigger, rawData, 2, bytesRead); // Check whether the read was successful if (err != kSTkErrOk) @@ -71,11 +72,14 @@ sfeTkError_t sfeQwiicUltrasonic::getTriggeredDistance(uint16_t &distance) sfeTkError_t sfeQwiicUltrasonic::changeAddress(const uint8_t &address) { // Check whether the address is valid + sfeTkError_t err; + if (address < kQwiicUltrasonicMinAddress || address > kQwiicUltrasonicMaxAddress) return kSTkErrFail; // Write the new address to the device. The first bit must be set to 1 - sfeTkError_t err = _theBus->writeByte(address | 0x80); + _theBus->writeRegisterByte(_theBus->address(), kUltrasonicAddressChangeCommand); + err = _theBus->writeRegisterByte(_theBus->address(), address << 1); // Check whether the write was successful if (err != kSTkErrOk) diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index eaaa4ed..c85a0b5 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -4,15 +4,12 @@ #include // Available I2C addresses of the Qwiic Ultrasonic -const uint8_t kQwiicUltrasonicAddresses[] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F}; -const uint8_t kQwiicUltrasonicNumAddresses = sizeof(kQwiicUltrasonicAddresses) / sizeof(uint8_t); -const uint8_t kQwiicUltrasonicMinAddress = kQwiicUltrasonicAddresses[0]; -const uint8_t kQwiicUltrasonicMaxAddress = kQwiicUltrasonicAddresses[15]; const uint8_t kQwiicUltrasonicDefaultAddress = 0x2F; - -// Register to trigger a new measuremnt and read the previous one -const uint8_t kQwiicUltrasonicRegisterTrigger = 0x01; +const uint8_t kQwiicUltrasonicMinAddress = 0x08; +const uint8_t kQwiicUltrasonicMaxAddress = 0x7F; +// I2C commands +const uint8_t kUltrasonicDistanceReadCommand = 0x01; +const uint8_t kUltrasonicAddressChangeCommand = 0x04; class sfeQwiicUltrasonic { @@ -46,7 +43,7 @@ class sfeQwiicUltrasonic /// @return 0 for succuss, negative for errors, positive for warnings sfeTkError_t changeAddress(const uint8_t &address); - /// @brief Gets the current I2C address of the Qwiic Ultrasonic sensor + /// @brief Gets the current I2C address being used by the library for the Qwiic Ultrasonic sensor /// @return The current I2C address, 7-bit unshifted uint8_t getAddress(); From 11ad0f148fb750cc14be4178ef5338f0387279d5 Mon Sep 17 00:00:00 2001 From: santised Date: Wed, 29 May 2024 12:29:36 -0600 Subject: [PATCH 05/34] Updates examples, add comments, and licenses * Temporarily adds SparkFun Toolkit --- .../HC-SR04_UltrasonicSensorExample.ino | 331 ------------------ .../desktop.ini | 5 - Arduino/desktop.ini | 5 - .../example1_basic_distance.ino | 60 ---- .../example2_basic_distance_trigger.ino | 72 ---- .../example3_change_address.ino | 55 --- .../Example1_BasicReadings.ino | 62 ++-- .../Example2_ChangeAddress.ino | 94 ----- .../Example2_basic_distance_trigger.ino | 80 +++++ .../Example3_ChangeAddress.ino | 75 ++++ .../Example4_OLED_Distance.ino | 100 ++++++ ...parkFun_Qwiic_Ultrasonic_Arduino_Library.h | 11 + src/SparkFun_Toolkit.h | 37 ++ src/sfeQwiicUltrasonic.cpp | 24 +- src/sfeQwiicUltrasonic.h | 13 +- src/sfeTk/sfeTkError.h | 64 ++++ src/sfeTk/sfeTkIBus.h | 192 ++++++++++ src/sfeTk/sfeTkII2C.h | 117 +++++++ src/sfeTk/sfeTkISPI.h | 90 +++++ src/sfeTk/sfeToolkit.h | 32 ++ src/sfeTkArdI2C.cpp | 312 +++++++++++++++++ src/sfeTkArdI2C.h | 266 ++++++++++++++ src/sfeTkArdSPI.cpp | 281 +++++++++++++++ src/sfeTkArdSPI.h | 192 ++++++++++ 24 files changed, 1916 insertions(+), 654 deletions(-) delete mode 100644 Arduino/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino delete mode 100644 Arduino/HC-SR04_UltrasonicSensorExample/desktop.ini delete mode 100644 Arduino/desktop.ini delete mode 100644 Arduino/example1_basic_distance/example1_basic_distance.ino delete mode 100644 Arduino/example2_basic_distance_trigger/example2_basic_distance_trigger.ino delete mode 100644 Arduino/example3_change_address/example3_change_address.ino delete mode 100644 examples/Example2_ChangeAddress/Example2_ChangeAddress.ino create mode 100644 examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino create mode 100644 examples/Example3_ChangeAddress/Example3_ChangeAddress.ino create mode 100644 examples/Example4_OLED_Distance/Example4_OLED_Distance.ino create mode 100644 src/SparkFun_Toolkit.h create mode 100644 src/sfeTk/sfeTkError.h create mode 100644 src/sfeTk/sfeTkIBus.h create mode 100644 src/sfeTk/sfeTkII2C.h create mode 100644 src/sfeTk/sfeTkISPI.h create mode 100644 src/sfeTk/sfeToolkit.h create mode 100644 src/sfeTkArdI2C.cpp create mode 100644 src/sfeTkArdI2C.h create mode 100644 src/sfeTkArdSPI.cpp create mode 100644 src/sfeTkArdSPI.h diff --git a/Arduino/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino b/Arduino/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino deleted file mode 100644 index 7244c63..0000000 --- a/Arduino/HC-SR04_UltrasonicSensorExample/HC-SR04_UltrasonicSensorExample.ino +++ /dev/null @@ -1,331 +0,0 @@ -/** - * HC-SR04 Demo - * Demonstration of the HC-SR04 Ultrasonic Sensor - * Date: August 3, 2016 - * - * Description: - * Connect the ultrasonic sensor to the Arduino as per the - * hardware connections below. Run the sketch and open a serial - * monitor. The distance read from the sensor will be displayed - * in centimeters and inches. - * - * Hardware Connections: - * Arduino | HC-SR04 - * ------------------- - * 5V | VCC - * 7 | Trig - * 8 | Echo - * GND | GND - * - * License: - * Public Domain - */ -#include -#include -#include - -// Pins -const int TRIG_PIN = 7; -const int ECHO_PIN = 8; - -// Anything over 400 cm (23200 us pulse) is "out of range" -const unsigned int MAX_DIST = 23200; - -#define OLED_RESET 4 -Adafruit_SSD1306 display(OLED_RESET); - -#define NUMFLAKES 10 -#define XPOS 0 -#define YPOS 1 -#define DELTAY 2 - - -#define LOGO16_GLCD_HEIGHT 16 -#define LOGO16_GLCD_WIDTH 16 -static const unsigned char PROGMEM logo16_glcd_bmp[] = -{ B00000000, B11000000, - B00000001, B11000000, - B00000001, B11000000, - B00000011, B11100000, - B11110011, B11100000, - B11111110, B11111000, - B01111110, B11111111, - B00110011, B10011111, - B00011111, B11111100, - B00001101, B01110000, - B00011011, B10100000, - B00111111, B11100000, - B00111111, B11110000, - B01111100, B11110000, - B01110000, B01110000, - B00000000, B00110000 }; - -#if (SSD1306_LCDHEIGHT != 32) -#error("Height incorrect, please fix Adafruit_SSD1306.h!"); -#endif - -void setup() { - - // The Trigger pin will tell the sensor to range find - pinMode(TRIG_PIN, OUTPUT); - digitalWrite(TRIG_PIN, LOW); - - // We'll use the serial monitor to view the sensor output - Serial.begin(9600); - display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32) - display.clearDisplay(); -} - -void loop() { - - unsigned long t1; - unsigned long t2; - unsigned long pulse_width; - float cm; - float inches; - - // Hold the trigger pin high for at least 10 us - digitalWrite(TRIG_PIN, HIGH); - delayMicroseconds(50); - digitalWrite(TRIG_PIN, LOW); - - // Wait for pulse on echo pin - while ( digitalRead(ECHO_PIN) == 0 ); - - // Measure how long the echo pin was held high (pulse width) - // Note: the micros() counter will overflow after ~70 min - t1 = micros(); - while ( digitalRead(ECHO_PIN) == 1); - t2 = micros(); - pulse_width = t2 - t1; - - // Calculate distance in centimeters and inches. The constants - // are found in the datasheet, and calculated from the assumed speed - //of sound in air at sea level (~340 m/s). - cm = pulse_width / 58.0; - inches = pulse_width / 148.0; - - // Print out results - if ( pulse_width > MAX_DIST ) { - Serial.println("Out of range"); - } else { - Serial.print(cm); - Serial.print(" cm \t"); - Serial.print(inches); - Serial.println(" in"); - display.setTextSize(2); - display.setTextColor(WHITE); - display.setCursor(10,0); - display.clearDisplay(); - display.print(cm); - display.print("cm"); - display.display(); - delay(1); - - } - - // Wait at least 60ms before next measurement - delay(60); -} -void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) { - uint8_t icons[NUMFLAKES][3]; - - // initialize - for (uint8_t f=0; f< NUMFLAKES; f++) { - icons[f][XPOS] = random(display.width()); - icons[f][YPOS] = 0; - icons[f][DELTAY] = random(5) + 1; - - Serial.print("x: "); - Serial.print(icons[f][XPOS], DEC); - Serial.print(" y: "); - Serial.print(icons[f][YPOS], DEC); - Serial.print(" dy: "); - Serial.println(icons[f][DELTAY], DEC); - } - - while (1) { - // draw each icon - for (uint8_t f=0; f< NUMFLAKES; f++) { - display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE); - } - display.display(); - delay(200); - - // then erase it + move it - for (uint8_t f=0; f< NUMFLAKES; f++) { - display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK); - // move it - icons[f][YPOS] += icons[f][DELTAY]; - // if its gone, reinit - if (icons[f][YPOS] > display.height()) { - icons[f][XPOS] = random(display.width()); - icons[f][YPOS] = 0; - icons[f][DELTAY] = random(5) + 1; - } - } - } -} - - -void testdrawchar(void) { - display.setTextSize(1); - display.setTextColor(WHITE); - display.setCursor(0,0); - - for (uint8_t i=0; i < 168; i++) { - if (i == '\n') continue; - display.write(i); - if ((i > 0) && (i % 21 == 0)) - display.println(); - } - display.display(); - delay(1); -} - -void testdrawcircle(void) { - for (int16_t i=0; i0; i-=5) { - display.fillTriangle(display.width()/2, display.height()/2-i, - display.width()/2-i, display.height()/2+i, - display.width()/2+i, display.height()/2+i, WHITE); - if (color == WHITE) color = BLACK; - else color = WHITE; - display.display(); - delay(1); - } -} - -void testdrawroundrect(void) { - for (int16_t i=0; i=0; i-=4) { - display.drawLine(0, display.height()-1, display.width()-1, i, WHITE); - display.display(); - delay(1); - } - delay(250); - - display.clearDisplay(); - for (int16_t i=display.width()-1; i>=0; i-=4) { - display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE); - display.display(); - delay(1); - } - for (int16_t i=display.height()-1; i>=0; i-=4) { - display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE); - display.display(); - delay(1); - } - delay(250); - - display.clearDisplay(); - for (int16_t i=0; i -const int ULTRA_ADDR = 0x2F; -const int BEGIN_MEASURE = 0x01; -int distance, distance_H, distance_L=0; - -void setup() { - - Wire.begin(); - - Serial.begin(115200); - Serial.println("Ultrasonic Distance Sensor - Example 1 Basic Distance Sensing."); - - Wire.beginTransmission(ULTRA_ADDR); - int error = Wire.endTransmission(); - if(error != 0){ - Serial.print("Could not communicate with the sensor, check that you have the correct address, or that your sensor is connected."); - while(1) - ; - } - - Serial.println("Ready to check distance."); - Serial.println("\n\n"); - delay(1000); -} - -void loop() { - - Wire.beginTransmission(ULTRA_ADDR); - Wire.write(BEGIN_MEASURE); - Wire.endTransmission(); - delay(20); - - Wire.requestFrom(ULTRA_ADDR, 2); - delay(20); - - while (Wire.available()) { - distance_H = Wire.read(); - distance_L = Wire.read(); - distance = distance_H << 8; - distance = distance|distance_L; - - Serial.print("Distance: "); - Serial.print(distance); - Serial.println("mm"); - - //Serial.print("Distance: "); - //Serial.print(distance / 10.0); - //Serial.println("cm", 2); - - //Serial.print("Distance: "); - //Serial.print(distance / 25.4); - //Serial.println("in", 2); - } - - Serial.println("\n"); - delay(500); -} diff --git a/Arduino/example2_basic_distance_trigger/example2_basic_distance_trigger.ino b/Arduino/example2_basic_distance_trigger/example2_basic_distance_trigger.ino deleted file mode 100644 index 9ffaee4..0000000 --- a/Arduino/example2_basic_distance_trigger/example2_basic_distance_trigger.ino +++ /dev/null @@ -1,72 +0,0 @@ -/*SparkFun Ultrasonic Distance Sensor Example 2 - Basic Distance Sensing using I2C and Trigger Pin -* and Echo pin. -*/ - -#include -const int ULTRA_ADDR = 0x2F; -const int BEGIN_MEASURE = 0x01; -int distanceRequested = 0; -int distance, distance_H, distance_L=0; -int triggerPin = 7; // Trigger Pin of Ultrasonic Sensor -int echoPin = 8; // Echo Pin of Ultrasonic Sensor - -void setup() { - - Wire.begin(); - - Serial.begin(115200); - Serial.println("Ultrasonic Distance Sensor - Example 1 Basic Distance Sensing."); - - pinMode(triggerPin, OUTPUT); - pinMode(echoPin, INPUT); - - Wire.beginTransmission(ULTRA_ADDR); - int error = Wire.endTransmission(); - if(error != 0){ - Serial.print("Could not communicate with the sensor, check that you have the correct address, or that your sensor is connected."); - while(1) - ; - } - - Serial.println("Ready to check distance."); - Serial.println("\n\n"); - delay(1000); -} - -void loop() { - - if(distanceRequested == 0) - { - digitalWrite(triggerPin, HIGH); - delay(5); - digitalWrite(triggerPin, LOW); - distanceRequested = 1; - } - - if (digitalRead(echoPin) == LOW) { - Wire.requestFrom(ULTRA_ADDR, 2); - delay(20); - - while (Wire.available()) { - distance_H = Wire.read(); - distance_L = Wire.read(); - distance = distance_H << 8; - distance = distance|distance_L; - - Serial.print("Distance: "); - Serial.print(distance); - Serial.println("mm"); - - //Serial.print("Distance: "); - //Serial.print(distance / 10.0); - //Serial.println("cm", 2); - - //Serial.print("Distance: "); - //Serial.print(distance / 25.4); - //Serial.println("in", 2); - Serial.println("\n"); - } - distanceRequested = 0; - } - delay(500); -} diff --git a/Arduino/example3_change_address/example3_change_address.ino b/Arduino/example3_change_address/example3_change_address.ino deleted file mode 100644 index 9038819..0000000 --- a/Arduino/example3_change_address/example3_change_address.ino +++ /dev/null @@ -1,55 +0,0 @@ -/*SparkFun Ultrasonic Distance Sensor Example 2 - Basic Distance Sensing using I2C and Trigger Pin -* and Echo pin. -*/ -#include -const int ULTRA_ADDR = 0x2F; -const int CHANGE_ADDR = 0x04; -const int NEW_ADDR = 0x1F; -int error; - -void setup() { - - Wire.begin(); - - Serial.begin(115200); - Serial.println("Ultrasonic Distance Sensor - Example 4 - Change Address"); - - Wire.beginTransmission(ULTRA_ADDR); - error = Wire.endTransmission(); - if(error != 0){ - Serial.print("Could not communicate with the sensor, check that you have the correct address, or that your sensor is connected."); - while(1) - ; - } - - Serial.println("Ready to change address."); - Serial.println("\n\n"); - delay(1000); -} - -void loop() { - - Serial.print("Changing address to: "); - Serial.println(NEW_ADDR, HEX); - Wire.beginTransmission(ULTRA_ADDR); - Wire.write(CHANGE_ADDR); - Wire.write(NEW_ADDR << 1); - Wire.endTransmission(); - - delay(1000); - - Wire.beginTransmission((NEW_ADDR); - error = Wire.endTransmission(); - if(error == 0){ - Serial.print("Address changed to: "); - Serial.println(NEW_ADDR, HEX); - while(1) - ; - } - else{ - Serial.println("Address did not change."); - Serial.println(error); - } - while(1) - ; -} diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index 4da6cfe..934d386 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -1,4 +1,18 @@ -#include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" +/* SparkFun Ulrasonic Distance Sensor - Example 1 Basic Distance Sensing + * + * Product: + * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) + * * https://www.sparkfun.com/1XXXX + * + * Written By: Elias Santistevan + * Date: 06/2024 + * + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2024 SparkFun Electronics + */ + +#include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h"/* // Create an ultrasonic sensor object QwiicUltrasonic myUltrasonic; @@ -12,38 +26,38 @@ uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F void setup() { - // Start serial - Serial.begin(115200); - Serial.println("Ultrasonic Distance Sensor Example 1 - Basic Distance Sensing"); + // Start serial + Serial.begin(115200); + Serial.println("Ultrasonic Distance Sensor Example 1 - Basic Distance Sensing"); - Wire.begin(); + Wire.begin(); - // Attempt to begin the sensor - while (myUltrasonic.begin(deviceAddress) == false) - { - Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); - while(1) - ; - } + // Attempt to begin the sensor + if (myUltrasonic.begin(deviceAddress) == false) + { + Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); + while(1) + ; + } - Serial.println("Ultrasonic sensor connected!"); + Serial.println("Ultrasonic sensor connected!"); } void loop() { - uint16_t distance = 0; - myUltrasonic.getDistance(distance); + uint16_t distance = 0; + myUltrasonic.getDistance(distance); - // Print measurement - Serial.print("Distance (mm): "); - Serial.println(distance); + // Print measurement + Serial.print("Distance (mm): "); + Serial.println(distance); - //Serial.println("Distance (cm): "); - //Serial.print((distance / 10.0), 2); + //Serial.println("Distance (cm): "); + //Serial.print((distance / 10.0), 2); - //Serial.println("Distace (in): "); - //Serial.print((distance / 25.4), 2); + //Serial.println("Distace (in): "); + //Serial.print((distance / 25.4), 2); - // Wait a bit - delay(250); + // Wait a bit + delay(250); } diff --git a/examples/Example2_ChangeAddress/Example2_ChangeAddress.ino b/examples/Example2_ChangeAddress/Example2_ChangeAddress.ino deleted file mode 100644 index c94577c..0000000 --- a/examples/Example2_ChangeAddress/Example2_ChangeAddress.ino +++ /dev/null @@ -1,94 +0,0 @@ -#include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" - -// Create an ultrasonic sensor object -QwiicUltrasonic myUltrasonic; - -// Here we set the device address. Note that an older version of the Qwiic -// Ultrasonic firmware used a default address of 0x00. If yours uses 0x00, -// you'll need to change the address below. It is also recommended to run -// Example 2 to change the address to the new default. -uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F -// uint8_t deviceAddress = 0x00; - -void setup() -{ - // Start serial - Serial.begin(115200); - Serial.println("Qwiic Ultrasonic Example 2 - Change Address"); - - Wire.begin(); - - // Attempt to begin the sensor - while (myUltrasonic.begin(deviceAddress) == false) - { - Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); - delay(1000); - } - - Serial.println("Ultrasonic sensor connected!"); - - // Repeat until the address has been successfully changed - bool addressChanged = false; - while (addressChanged == false) - { - // Print instructions - Serial.println(); - Serial.println("Please enter a new address for the sensor."); - Serial.println("Any value between 0x20 and 0x2F is valid."); - Serial.println("Enter the address in hexadecimal without the `0x`."); - Serial.println(); - - // Clear serial buffer and wait for input - while (Serial.available() > 0) - Serial.read(); - while (Serial.available() == 0) - ; - - // Read input from user - char input[4]; // Only expecting a few characters - size_t numBytesRead = Serial.readBytesUntil('\n', input, 4); - - // Parse input using strtoul (STRing TO Unsigned Long integer) - uint8_t newAddress = strtoul(input, nullptr, 16); - - Serial.print("Parsed address: "); - Serial.println(newAddress, HEX); - - // Check if the address is valid - if (newAddress < kQwiicUltrasonicMinAddress || newAddress > kQwiicUltrasonicMaxAddress) - { - Serial.println("Invalid address!"); - continue; - } - - // Address is valid, attempt to change it on the device - sfeTkError_t err = myUltrasonic.changeAddress(newAddress); - - // Check whether the address was changed successfully - if (err) - Serial.println("Failed to change address!"); - - // Success, we're done here! - addressChanged = true; - } - - Serial.println("Address changed successfully! Continuing..."); - - // Wait a moment so user can read the messages - delay(1000); -} - -void loop() -{ - // Get measurement from sensor. Note that the mesaured distance actually - // comes from the previous trigger, so measurements will be slightly delayed - uint16_t distance = 0; - myUltrasonic.triggerAndRead(distance); - - // Print measurement - Serial.print("Distance (mm): "); - Serial.println(distance); - - // Wait a bit - delay(100); -} \ No newline at end of file diff --git a/examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino b/examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino new file mode 100644 index 0000000..39d1339 --- /dev/null +++ b/examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino @@ -0,0 +1,80 @@ +/* SparkFun Ulrasonic Distance Sensor - Example 2 Basic Distance Sensing using Trigger and Echo Pins. + * + * Product: + * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) + * * https://www.sparkfun.com/1XXXX + * + * Written By: Elias Santistevan + * Date: 06/2024 + * + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2024 SparkFun Electronics + */ + +// Create an ultrasonic sensor object +QwiicUltrasonic myUltrasonic; + +// Here we set the device address. Note that an older version of the Qwiic +// Ultrasonic firmware used a default address of 0x00. If yours uses 0x00, +// you'll need to change the address below. It is also recommended to run +// Example 2 to change the address to the new default. +uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F +// uint8_t deviceAddress = 0x00; + +const int triggerPin = 7; // Trigger Pin of Ultrasonic Sensor +const int echoPin = 8; // Echo Pin of Ultrasonic Sensor +int distanceRequested = 0; + +void setup() { + + Wire.begin(); + + Serial.begin(115200); + Serial.println("Ultrasonic Distance Sensor - Example 2 Distance using Trigger and Echo Pins."); + + pinMode(triggerPin, OUTPUT); + pinMode(echoPin, INPUT); + + // Attempt to begin the sensor + if (myUltrasonic.begin(deviceAddress) == false) + { + Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); + while(1) + ; + } + + Serial.println("Ultrasonic sensor connected!"); +} + +void loop() { + + if(distanceRequested == 0) + { + // To trigger we write the pin high and then back to its resting state. + digitalWrite(triggerPin, HIGH); + delay(5); + digitalWrite(triggerPin, LOW); + // We don't want continually trigger while data is being retrieved from the sensor. + distanceRequested = 1; + } + + if (digitalRead(echoPin) == LOW) { + + uint16_t distance = 0; + myUltrasonic.getTriggeredDistance(distance); + + // Print measurement + Serial.print("Distance (mm): "); + Serial.println(distance); + + //Serial.println("Distance (cm): "); + //Serial.print((distance / 10.0), 2); + + //Serial.println("Distace (in): "); + //Serial.print((distance / 25.4), 2); + + distanceRequested = 0; + } + delay(500); +} diff --git a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino new file mode 100644 index 0000000..b45fa2f --- /dev/null +++ b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino @@ -0,0 +1,75 @@ +/* SparkFun Ulrasonic Distance Sensor - Example 3 Changing the Ultrasonic's Address + * To reset the original I2C address, ground the "RST" pad on the backside of the board. + * by touching a wire to the pad and then to ground. The address will be reset to 0x2F. + * + * Product: + * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) + * * https://www.sparkfun.com/1XXXX + * + * Written By: Elias Santistevan + * Date: 06/2024 + * + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2024 SparkFun Electronics + */ + +#include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" + +// Create an ultrasonic sensor object +QwiicUltrasonic myUltrasonic; + +// Here we set the device address. Note that an older version of the Qwiic +// Ultrasonic firmware used a default address of 0x00. If yours uses 0x00, +// you'll need to change the address below. It is also recommended to run +// Example 2 to change the address to the new default. +uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F +// uint8_t deviceAddress = 0x00; +const uint8_t NEW_ADDR = 0x1E; + +void setup() +{ + // Start serial + Serial.begin(115200); + Serial.println("Ultrasonic Distance Sensor - Example 4 - Change Address"); + + Wire.begin(); + + while(!Serial) + ; + + // Attempt to begin the sensor + if (myUltrasonic.begin(deviceAddress) == false) + { + Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); + while(1) + ; + } + + Serial.println("Ready to change address."); + delay(1000); + +} + +void loop() +{ + Serial.print("Changing Address To: "); + Serial.println(NEW_ADDR, HEX); + // Call change address..... + myUltrasonic.changeAddress(NEW_ADDR); + delay(1000); + + Serial.println("Attempting to communicate with new address..."); + if (myUltrasonic.begin(NEW_ADDR) == false) + { + Serial.println("Ultrasonic sensor address did not change, ensure you picked a viable address."); + while(1) + ; + } + + Serial.println("Address changed successfully: "); + Serial.println(NEW_ADDR, HEX); + + while(1) + ; +} diff --git a/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino b/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino new file mode 100644 index 0000000..ae3c81f --- /dev/null +++ b/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino @@ -0,0 +1,100 @@ +/* SparkFun Ulrasonic Distance Sensor - Example 4 Basic Distance Sensing on an OLED Display + * + * Products: + * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) + * * https://www.sparkfun.com/1XXXX + * * SparkFun Qwiic Narrow OLED Display (LCD-1XXXX) + * * https://www.sparkfun.com/1XXXX + * + * Written By: Elias Santistevan + * Date: 06/2024 + * + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2024 SparkFun Electronics + */ + +#include "SparkFun_Qwiic_OLED.h" +// For the narrow LED, I prefer the slightly larger font included in the OLED library. +// This is completely optional and can be deleted or commented out. By default the font +// is slightly smaller. +#include "res/qw_fnt_8x16.h" +#include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" + +const int TRIG_PIN = 7; +const int ECHO_PIN = 8; + +// Create an ultrasonic sensor object +QwiicUltrasonic myUltrasonic; +// Creat an OLED object +QwiicNarrowOLED myOLED; + +char distanceBuff[4] = {}; +String distanceStr = ""; +int centerX; +int centerY; + +// Here we set the device address. Note that an older version of the Qwiic +// Ultrasonic firmware used a default address of 0x00. If yours uses 0x00, +// you'll need to change the address below. It is also recommended to run +// Example 2 to change the address to the new default. +uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F +// uint8_t deviceAddress = 0x00; + +void setup() +{ + + Serial.begin(115200); // Default config settings + Serial.println("Ultrasonic Distance Sensor - Example 4 - Distance on an OLED Display"); + Wire.begin(); + + if (myOLED.begin() == false) { + Serial.println("OLED sensor not connected, check your wiring and I2C address!"); + while (1) + ; + } + if (myUltrasonic.begin(deviceAddress) == false) + { + Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); + while(1) + ; + } + String hello = "Hello, Ultrasonic!"; + + // This is good for the narrow OLED screen. You can also just remove this + // and it will default to a slightly smaller font. + myOLED.setFont(QW_FONT_8X16); + + // This will center the text onto the screen. + int x0 = (myOLED.getWidth() - myOLED.getStringWidth(hello)) / 2; + int y0 = (myOLED.getHeight() - myOLED.getStringHeight(hello)) / 2; + + myOLED.text(x0, y0, hello); + + // There's nothing on the screen yet - Now send the graphics to the device + myOLED.display(); + delay(2000); +} + +void loop() +{ + uint16_t distance = 0; + myUltrasonic.getDistance(distance); + + // Convert distance, which is an integer, to char so that we can print it. + itoa(distance, distanceBuff, 10); + + // Put the distance in a string so that we can also print "mm". + distanceStr = distanceBuff; + distanceStr += "mm"; + + myOLED.erase(); + centerX = (myOLED.getWidth() - myOLED.getStringWidth(distanceStr)) / 2; + centerY = (myOLED.getHeight() - myOLED.getStringHeight(distanceStr)) / 2; + myOLED.text(centerX, centerY, distanceStr); + myOLED.display(); + + delay(250); +} + + diff --git a/src/SparkFun_Qwiic_Ultrasonic_Arduino_Library.h b/src/SparkFun_Qwiic_Ultrasonic_Arduino_Library.h index 494fd9d..138065d 100644 --- a/src/SparkFun_Qwiic_Ultrasonic_Arduino_Library.h +++ b/src/SparkFun_Qwiic_Ultrasonic_Arduino_Library.h @@ -1,3 +1,14 @@ +/* SparkFun Ulrasonic Distance Sensor + * + * Product: + * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) + * * https://www.sparkfun.com/1XXXX + * + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2024 SparkFun Electronics + */ + #pragma once #include "Arduino.h" diff --git a/src/SparkFun_Toolkit.h b/src/SparkFun_Toolkit.h new file mode 100644 index 0000000..ffe3da6 --- /dev/null +++ b/src/SparkFun_Toolkit.h @@ -0,0 +1,37 @@ + +/* +SparkFun_Toolkit.h + +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#pragma once + +// Purpose: +// +// The SparkFun Toolkit provides a set of common implementations used throughout our (and others) +// Arduino Libraries. + +// Just include the toolkit headers + +#include +#include "sfeTkArdI2C.h" +#include "sfeTkArdSPI.h" \ No newline at end of file diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 530095b..28ddb75 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -1,4 +1,16 @@ +/* SparkFun Ulrasonic Distance Sensor + * + * Product: + * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) + * * https://www.sparkfun.com/1XXXX + * + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2024 SparkFun Electronics + */ + #include "sfeQwiicUltrasonic.h" +#include sfeTkError_t sfeQwiicUltrasonic::begin(sfeTkII2C *theBus) { @@ -29,15 +41,14 @@ sfeTkError_t sfeQwiicUltrasonic::isConnected() return _theBus->ping(); } -sfeTkError_t sfeQwiicUltrasonic::getDistace(uint16_t &distance) +sfeTkError_t sfeQwiicUltrasonic::getDistance(uint16_t &distance) { size_t bytesRead = 0; uint8_t rawData[2] = {0, 0}; sfeTkError_t err; - _theBus->writeRegisterByte(theBus->address(), kUltrasonicDistanceReadCommand); - delay(10); - err = _theBus->readRegisterRegion(kQwiicUltrasonicRegisterTrigger, rawData, 2, bytesRead); + _theBus->writeByte(kUltrasonicDistanceReadCommand); + err = _theBus->readRegisterRegion(_theBus->address(), rawData, 2, bytesRead); // Check whether the read was successful if (err != kSTkErrOk) @@ -56,7 +67,7 @@ sfeTkError_t sfeQwiicUltrasonic::getTriggeredDistance(uint16_t &distance) uint8_t rawData[2] = {0, 0}; // Attempt to read the distance - sfeTkError_t err = _theBus->readRegisterRegion(kQwiicUltrasonicRegisterTrigger, rawData, 2, bytesRead); + sfeTkError_t err = _theBus->readRegisterRegion(_theBus->address(), rawData, 2, bytesRead); // Check whether the read was successful if (err != kSTkErrOk) @@ -78,8 +89,7 @@ sfeTkError_t sfeQwiicUltrasonic::changeAddress(const uint8_t &address) return kSTkErrFail; // Write the new address to the device. The first bit must be set to 1 - _theBus->writeRegisterByte(_theBus->address(), kUltrasonicAddressChangeCommand); - err = _theBus->writeRegisterByte(_theBus->address(), address << 1); + err = _theBus->writeRegisterByte(kUltrasonicAddressChangeCommand, (address<< 1)); // Check whether the write was successful if (err != kSTkErrOk) diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index c85a0b5..99ca9f6 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -1,3 +1,14 @@ +/* SparkFun Ulrasonic Distance Sensor + * + * Product: + * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) + * * https://www.sparkfun.com/1XXXX + * + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2024 SparkFun Electronics + */ + #pragma once #include "SparkFun_Toolkit.h" @@ -31,7 +42,7 @@ class sfeQwiicUltrasonic /// @brief Triggers a new measurement and reads the previous one /// @param distance Distance in mm /// @return 0 for succuss, negative for errors, positive for warnings - sfeTkError_t getDistace(uint16_t &distance); + sfeTkError_t getDistance(uint16_t &distance); /// @brief Triggers a new measurement and reads the previous one /// @param distance Distance in mm diff --git a/src/sfeTk/sfeTkError.h b/src/sfeTk/sfeTkError.h new file mode 100644 index 0000000..3f00841 --- /dev/null +++ b/src/sfeTk/sfeTkError.h @@ -0,0 +1,64 @@ + +// sfeTkError.h +// +// General header file for the SparkFun Toolkit +/* +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#pragma once + +#include + +/** + * General Concept + * A SparkFun Toolkit error system. The goal is to keep this simple. + * + * This mimics a variety of systems, using an int type for error codes, + * where: + * 0 = okay + * -1 = general failure + * >0 = an informative error + * + * Since *subsystems* in the toolkit can have their own errors, + * A start range for these errors are defined. Values > than this value + * define the errors for the set subsystem. These start ranges are set + * in this file, with actual error values defined in the the respective + * subsystem header files. + * + */ +typedef int32_t sfeTkError_t; + +// General errors + +/** + * @brief General error code for a failure. Note all errors are negative. + */ +const sfeTkError_t kSTkErrFail = -1; // general fail +/** + * @brief The error code value for success. This is always 0. + */ +const sfeTkError_t kSTkErrOk = 0; // success + +/** + * @brief A base value for bus errors. All bus errors are greater than this value, in the 1000 range + */ +const sfeTkError_t kSTkErrBaseBus = 0x1000; diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h new file mode 100644 index 0000000..003a914 --- /dev/null +++ b/src/sfeTk/sfeTkIBus.h @@ -0,0 +1,192 @@ + +// sfeTkIBus.h +// +// Defines the communication bus interface for the SparkFun Electronics Toolkit -> sfeTk +/* + +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#pragma once + +#include "sfeTkError.h" +#include + +/** + * @brief Define our error codes for the bus. Note Errors are negative, warnings/info positive, + * but keep the same increment on the base. + * + */ + +/** + * @brief Error code for when a bus system is not initalized. + */ +const sfeTkError_t kSTkErrBusNotInit = kSTkErrFail * (kSTkErrBaseBus + 1); + +/** + * @brief Returned when a bus system times out. + */ +const sfeTkError_t kSTkErrBusTimeout = kSTkErrFail * (kSTkErrBaseBus + 2); + +/** + * @brief Returned when a bus system does not respond. + */ +const sfeTkError_t kSTkErrBusNoResponse = kSTkErrFail * (kSTkErrBaseBus + 3); + +/** + * @brief Returned when the data to be sent is too long or recieved is too short. + */ +const sfeTkError_t kSTkErrBusDataTooLong = kSTkErrFail * (kSTkErrBaseBus + 4); + +/** + * @brief Returned when the bus settings are null, invalid or on set/initialised + */ +const sfeTkError_t kSTkErrBusNullSettings = kSTkErrFail * (kSTkErrBaseBus + 5); + +/** + * @brief Returned when the buffer is null or invalid. + */ +const sfeTkError_t kSTkErrBusNullBuffer = kSTkErrFail * (kSTkErrBaseBus + 6); + +/** + * @brief Returned when the bus is under read. Warning + */ +const sfeTkError_t kSTkErrBusUnderRead = kSTkErrBaseBus + 7; + +/** + * @brief Returned when the bus is not enabled. Warning + */ +const sfeTkError_t kSTkErrBusNotEnabled = kSTkErrBaseBus + 8; + +/** + * @brief Interface that defines the communication bus for the SparkFun Electronics Toolkit. + * + * The bus interface defines the basic methods for reading and writing data to a device. Specific + * bus implementations will extend this interface to provide the necessary functionality for the + * desired bus type. + */ +class sfeTkIBus +{ + public: + /**-------------------------------------------------------------------------- + * @brief Write a single byte to the device* + * @param data Data to write. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + * + */ + virtual sfeTkError_t writeByte(uint8_t data) = 0; + + /**-------------------------------------------------------------------------- + * @brief Write a single byte to the given register + * + * @param devReg The device's register's address. + * @param data Data to write. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + * + */ + virtual sfeTkError_t writeRegisterByte(uint8_t devReg, uint8_t data) = 0; + + /**-------------------------------------------------------------------------- + * @brief Write a single word (16 bit) to the given register + * + * @param devReg The device's register's address. + * @param data Data to write. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + * + */ + virtual sfeTkError_t writeRegisterWord(uint8_t devReg, uint16_t data) = 0; + + /**-------------------------------------------------------------------------- + * @brief Writes a number of bytes starting at the given register's address. + * + * @param devReg The device's register's address. + * @param data Data to write. + * @param length - length of data + * + * @retval sfeTkError_t kSTkErrOk on successful execution + * + */ + virtual sfeTkError_t writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length) = 0; + + /**-------------------------------------------------------------------------- + * @brief Writes a number of bytes starting at the given register's 16-bit address. + * + * @param devReg The device's register's address. + * @param data Data to write. + * @param length - length of data + * + * @retval sfeTkError_t kSTkErrOk on successful execution + * + */ + virtual sfeTkError_t writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length) = 0; + + /**-------------------------------------------------------------------------- + * @brief Read a single byte from the given register + * + * @param devReg The device's register's address. + * @param data Data to read. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + * + */ + virtual sfeTkError_t readRegisterByte(uint8_t devReg, uint8_t &data) = 0; + + /**-------------------------------------------------------------------------- + * @brief Read a single word (16 bit) from the given register + * + * @param devReg The device's register's address. + * @param data Data to read. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + */ + virtual sfeTkError_t readRegisterWord(uint8_t devReg, uint16_t &data) = 0; + + /**-------------------------------------------------------------------------- + * @brief Reads a block of data from the given register. + * + * @param reg The device's register's address. + * @param data Data to write. + * @param numBytes - length of data + * @param[out] readBytes - number of bytes read + * + * @retval int returns kSTkErrOk on success, or kSTkErrFail code + * + */ + virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes) = 0; + + /**-------------------------------------------------------------------------- + * @brief Reads a block of data from the given 16-bit register address. + * + * @param reg The device's 16 bit register's address. + * @param data Data to write. + * @param numBytes - length of data + * @param[out] readBytes - number of bytes read + * + * @retval int returns kSTkErrOk on success, or kSTkErrFail code + * + */ + virtual sfeTkError_t readRegister16Region(uint16_t reg, uint8_t *data, size_t numBytes, size_t &readBytes) = 0; +}; + +//}; diff --git a/src/sfeTk/sfeTkII2C.h b/src/sfeTk/sfeTkII2C.h new file mode 100644 index 0000000..f9fdf57 --- /dev/null +++ b/src/sfeTk/sfeTkII2C.h @@ -0,0 +1,117 @@ + +// sfeTkII2C.h +// +// Defines the I2C communication bus interface for the SparkFun Electronics Toolkit +/* +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#pragma once + +#include "sfeTkIBus.h" + +/** + * @brief Interface that defines the I2C communication bus for the SparkFun Electronics Toolkit. + * + * The I2C bus interface extends the IBus interface and adds the ability to set and get the I2C + * address and stop flag. + */ +class sfeTkII2C : public sfeTkIBus +{ + public: + // set the address to No address and stop flag to true + /** + * @brief Constructor for the I2C bus + */ + sfeTkII2C() : _address{kNoAddress}, _stop{true} + { + } + /** + * @brief Constructor for the I2C bus with an address passed in + * + * @param addr + */ + sfeTkII2C(uint8_t addr) : _address{addr} + { + } + + /**-------------------------------------------------------------------------- + @brief A simple ping of the device at the set address + + @retval sfeTkError_t - ok on success + + */ + virtual sfeTkError_t ping() = 0; + + /**-------------------------------------------------------------------------- + @brief setter for the I2C address + + @param devAddr The device's address + + */ + virtual void setAddress(uint8_t devAddr) + { + _address = devAddr; + } + + /**-------------------------------------------------------------------------- + @brief getter for the I2C address + + @retval uint8_t returns the address for the device + + */ + virtual uint8_t address(void) + { + return _address; + } + + /**-------------------------------------------------------------------------- + @brief setter for I2C stop message (vs restarts) + + @param stop The value to set for "send stop" + */ + virtual void setStop(bool stop) + { + _stop = stop; + } + + /**-------------------------------------------------------------------------- + @brief getter for I2C stops message (vs restarts) + + @retval bool returns the value of "send stop" + + */ + virtual bool stop(void) + { + return _stop; + } + + /** + * @brief kNoAddress is a constant to indicate no address has been set + */ + static constexpr uint8_t kNoAddress = 0; + + private: + uint8_t _address; + bool _stop; +}; + +//}; diff --git a/src/sfeTk/sfeTkISPI.h b/src/sfeTk/sfeTkISPI.h new file mode 100644 index 0000000..e9df115 --- /dev/null +++ b/src/sfeTk/sfeTkISPI.h @@ -0,0 +1,90 @@ + +// sfeTkISPI.h +// +// Defines the SPI communication bus interface for the SparkFun Electronics Toolkit +/* + +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#pragma once + +#include "sfeTkIBus.h" + +/** + * @brief Interface that defines the SPI communication bus for the SparkFun Electronics Toolkit. + * + * The SPI bus interface extends the IBus interface and adds the ability to set and get the CS pin. + */ +class sfeTkISPI : public sfeTkIBus +{ + public: + /**-------------------------------------------------------------------------- + @brief Constructor for the SPI bus + + */ + sfeTkISPI() : _cs{kNoCSPin} + { + } + + /**-------------------------------------------------------------------------- + @brief Constructor for the SPI bus + + @param csPin The CS Pin for the device + + */ + sfeTkISPI(uint8_t csPin) : _cs{csPin} + { + } + + /**-------------------------------------------------------------------------- + @brief setter for the CS Pin + + @param devCS The device's CS Pin + + */ + virtual void setCS(uint8_t devCS) + { + _cs = devCS; + } + + /**-------------------------------------------------------------------------- + @brief getter for the cs pin + + @retval uint8_t returns the CS pin for the device + + */ + virtual uint8_t cs(void) + { + return _cs; + } + + /**-------------------------------------------------------------------------- + @brief A constant for no CS pin + */ + static constexpr uint8_t kNoCSPin = 0; + + private: + /** The internal storage of the _cs value*/ + uint8_t _cs; +}; + +//}; diff --git a/src/sfeTk/sfeToolkit.h b/src/sfeTk/sfeToolkit.h new file mode 100644 index 0000000..da1ec00 --- /dev/null +++ b/src/sfeTk/sfeToolkit.h @@ -0,0 +1,32 @@ + +// sfeToolkit.h +// +// General header file for the SparkFun Toolkit +/* + +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#pragma once + +/** + @brief Common include file for the core of the SparkFun Electronics Toolkit +*/ +#include "sfeTkError.h" diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp new file mode 100644 index 0000000..146ef19 --- /dev/null +++ b/src/sfeTkArdI2C.cpp @@ -0,0 +1,312 @@ +/* +sfeTkArdI2C.cpp +*/ + +#include "sfeTkArdI2C.h" + +//--------------------------------------------------------------------------------- +// init() +// +// Arduino version of init - pass in already setup wire port ... +// +sfeTkError_t sfeTkArdI2C::init(TwoWire &wirePort, uint8_t addr, bool bInit) +{ + // if we don't have a wire port already + if (!_i2cPort) + { + // use the pass in port + _i2cPort = &wirePort; + + if (bInit) + _i2cPort->begin(); + } + + setAddress(addr); + return kSTkErrOk; +} + +//--------------------------------------------------------------------------------- +// init() +// +// no parameters version of init. Setups a a wire port if needed. +// +sfeTkError_t sfeTkArdI2C::init(uint8_t addr) +{ + // no port yet, do the default version of it + if (!_i2cPort) + return init(Wire, addr); + + // We have a port, so arcady init'd - right? + return kSTkErrOk; +} + +//--------------------------------------------------------------------------------- +// init() +// +// no parameters version of init. Setups a a wire port if needed. +// +sfeTkError_t sfeTkArdI2C::init(void) +{ + // call with our currently set address ... + return init(address()); +} +//--------------------------------------------------------------------------------- +// ping() +// +// Ping an I2C address to see if something is there. +// +sfeTkError_t sfeTkArdI2C::ping() +{ + // no port, no + if (!_i2cPort) + return kSTkErrBusNotInit; + + _i2cPort->beginTransmission(address()); + return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; +} + +//--------------------------------------------------------------------------------- +// writeByte() +// +// Writes a single byte to the device. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::writeByte(uint8_t dataToWrite) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + // do the Arduino I2C work + _i2cPort->beginTransmission(address()); + _i2cPort->write(dataToWrite); + return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; +} + +//--------------------------------------------------------------------------------- +// writeRegisterByte() +// +// Writes a byte to a given register. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::writeRegisterByte(uint8_t devReg, uint8_t dataToWrite) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + // do the Arduino I2C work + _i2cPort->beginTransmission(address()); + _i2cPort->write(devReg); + _i2cPort->write(dataToWrite); + return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; +} + +//--------------------------------------------------------------------------------- +// writeRegisterWord() +// +// Writes a word to a given register. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::writeRegisterWord(uint8_t devReg, uint16_t dataToWrite) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + return writeRegisterRegion(devReg, (uint8_t *)&dataToWrite, sizeof(uint16_t)); +} + +/** + * @brief Writes an array of bytes to a register on the target address. Supports any address size + * + * @param devReg The device's register's address - can be any size + * @param regLength The length of the register address + * @param data The data to write + * @param length The length of the data buffer + * @return sfeTkError_t Returns kSTkErrOk on success, or kSTkErrFail code + */ +sfeTkError_t sfeTkArdI2C::writeRegisterRegionAddress(uint8_t *devReg, size_t regLength, const uint8_t *data, + size_t length) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + _i2cPort->beginTransmission(address()); + _i2cPort->write(devReg, regLength); + _i2cPort->write(data, (int)length); + + return _i2cPort->endTransmission() ? kSTkErrFail : kSTkErrOk; +} + +//--------------------------------------------------------------------------------- +// writeRegisterRegion() +// +// Writes an array of bytes to a given register on the target address +// +// Returns the number of bytes written, < 0 is an error +// +sfeTkError_t sfeTkArdI2C::writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length) +{ + return writeRegisterRegionAddress(&devReg, 1, data, length); +} + +//--------------------------------------------------------------------------------- +// write16BitRegisterRegion() +// +// Writes an array of bytes to a given 16-bit register on the target address +// +// Returns the number of bytes written, < 0 is an error +// +sfeTkError_t sfeTkArdI2C::writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length) +{ + devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff); + return writeRegisterRegionAddress((uint8_t *)&devReg, 2, data, length); +} + +//--------------------------------------------------------------------------------- + +/** + * @brief Reads an array of bytes to a register on the target address. Supports any address size + * + * @param devReg The device's register's address - can be any size + * @param regLength The length of the register address + * @param data The data to buffer to read into + * @param numBytes The length of the data buffer + * @param readBytes[out] The number of bytes read + * @return sfeTkError_t Returns kSTkErrOk on success, or kSTkErrFail code + */ +sfeTkError_t sfeTkArdI2C::readRegisterRegionAnyAddress(uint8_t *devReg, size_t regLength, uint8_t *data, + size_t numBytes, size_t &readBytes) +{ + + // got port + if (!_i2cPort) + return kSTkErrBusNotInit; + + // Buffer valid? + if (!data) + return kSTkErrBusNullBuffer; + + readBytes = 0; + + uint16_t nOrig = numBytes; // original number of bytes. + uint8_t nChunk; + uint16_t nReturned; + uint16_t i; // counter in loop + bool bFirstInter = true; // Flag for first iteration - used to send devRegister + + while (numBytes > 0) + { + if (bFirstInter) + { + _i2cPort->beginTransmission(address()); + + _i2cPort->write(devReg, regLength); + + if (_i2cPort->endTransmission(stop()) != 0) + return kSTkErrFail; // error with the end transmission + + bFirstInter = false; + } + + // We're chunking in data - keeping the max chunk to kMaxI2CBufferLength + nChunk = numBytes > _bufferChunkSize ? _bufferChunkSize : numBytes; + + // Request the bytes. If this is the last chunk, always send a stop + nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)(nChunk == numBytes ? true : stop())); + + // No data returned, no dice + if (nReturned == 0) + return kSTkErrBusUnderRead; // error + + // Copy the retrieved data chunk to the current index in the data segment + for (i = 0; i < nReturned; i++) + *data++ = _i2cPort->read(); + + // Decrement the amount of data received from the overall data request amount + numBytes = numBytes - nReturned; + + } // end while + + readBytes = nOrig - numBytes; // Bytes read. + + return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success +} + +//--------------------------------------------------------------------------------- +// readRegisterByte() +// +// Reads a byte to a given register. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + // Return value + uint8_t result = 0; + + int nData = 0; + + _i2cPort->beginTransmission(address()); + _i2cPort->write(devReg); + _i2cPort->endTransmission(stop()); + _i2cPort->requestFrom(address(), (uint8_t)1); + + while (_i2cPort->available()) // slave may send less than requested + { + result = _i2cPort->read(); // receive a byte as a proper uint8_t + nData++; + } + + if (nData == sizeof(uint8_t)) // Only update outputPointer if a single byte was returned + dataToRead = result; + + return (nData == sizeof(uint8_t) ? kSTkErrOk : kSTkErrFail); +} + +//--------------------------------------------------------------------------------- +// readRegisterWord() +// +// Reads a word to a given register. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + size_t nRead; + sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead); + + return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval); +} + +//--------------------------------------------------------------------------------- +// readRegisterRegion() +// +// Reads an array of bytes to a given register on the target address +// +// Returns the number of bytes read, < 0 is an error +// +sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) +{ + return readRegisterRegionAnyAddress(&devReg, 1, data, numBytes, readBytes); +} + +//--------------------------------------------------------------------------------- +// read16BitRegisterRegion() +// +// Reads an array of bytes to a given 16-bit register on the target address +// +// Returns the number of bytes read, < 0 is an error +// +sfeTkError_t sfeTkArdI2C::readRegister16Region(uint16_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) +{ + devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff); + return readRegisterRegionAnyAddress((uint8_t *)&devReg, 2, data, numBytes, readBytes); +} diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h new file mode 100644 index 0000000..f42837d --- /dev/null +++ b/src/sfeTkArdI2C.h @@ -0,0 +1,266 @@ +/* +sfeTkArdI2c.h + +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +The following classes specify the behavior for communicating +over Inter-Integrated Circuit (I2C) in Arduino + +*/ + +#pragma once + +#include +#include + +// Include our platform I2C interface definition. +#include + +/** + * @brief The sfeTkArdI2C implements an sfeTkII2C interface, defining the Arduino implementation for I2C in the Toolkit + */ + +class sfeTkArdI2C : public sfeTkII2C +{ + public: + /** + @brief Constructor + */ + sfeTkArdI2C(void) : _i2cPort(nullptr), _bufferChunkSize{kDefaultBufferChunk} + { + } + /** + @brief Constructor + + @param addr The address of the device + */ + sfeTkArdI2C(uint8_t addr) : sfeTkII2C(addr) + { + } + + /** + * @brief copy constructor + */ + sfeTkArdI2C(sfeTkArdI2C const &rhs) : sfeTkII2C(), _i2cPort{rhs._i2cPort} + { + } + + /** + * @brief Copy assignment + * + * @param rhs right hand side of the assignment + * @return value of the left hand side of the assignment + */ + sfeTkArdI2C &operator=(const sfeTkArdI2C &rhs) + { + _i2cPort = rhs._i2cPort; + return *this; + } + + /** + @brief Method sets up the required I2C settings. + @note This function provides a default I2C Port. + + @retval kSTkErrOk on successful execution. + */ + sfeTkError_t init(); + + /** + @brief - address version of the init method + + @param addr The address of the device + */ + sfeTkError_t init(uint8_t addr); + + /** + @brief Method sets up the required I2C settings. + + @param wirePort Port for I2C communication. + @param addr The address of the device + @param bInit This flag tracks whether the bus has been initialized. + + @retval kSTkErrOk on successful execution. + */ + sfeTkError_t init(TwoWire &wirePort, uint8_t addr, bool bInit = false); + + /** + @brief A simple ping of the device at the given address. + @note sfeTkIBus interface method + + @retval kSTkErrOk on success, + */ + sfeTkError_t ping(); + + /** + @brief Write a single byte to the device + @note sfeTkIBus interface method + + @param data Data to write. + + @retval returns kStkErrOk on success + */ + sfeTkError_t writeByte(uint8_t data); + + /** + @brief Write a single byte to the given register + @note sfeTkIBus interface method + + @param devReg The device's register's address. + @param data Data to write. + + @retval returns kStkErrOk on success + */ + sfeTkError_t writeRegisterByte(uint8_t devReg, uint8_t data); + + /** + @brief Write a single word to the given register + @note sfeTkIBus interface method + + @param devReg The device's register's address. + @param data Data to write. + + @retval returns kStkErrOk on success + */ + sfeTkError_t writeRegisterWord(uint8_t devReg, uint16_t data); + + /** + @brief Writes a number of bytes starting at the given register's address. + + @note sfeTkIBus interface method + @note This method is virtual to allow it to be overridden to support a device that requires a unique impl + + @param devReg The device's register's address. + @param data Data to write. + @param length - length of data + + @retval kStkErrOk on success + */ + sfeTkError_t writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length); + + /** + @brief Writes a number of bytes starting at the given register's 16-bit address. + + @param devReg The device's register's address - 16 bit. + @param data Data to write. + @param length - length of data + + @retval sfeTkError_t kSTkErrOk on successful execution + + */ + sfeTkError_t writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length); + + /** + @brief Reads a byte of data from the given register. + + @note sfeTkIBus interface method + + @param devReg The device's register's address. + @param[out] data Data to read. + + @retval kStkErrOk on success + */ + sfeTkError_t readRegisterByte(uint8_t devReg, uint8_t &data); + + /** + @brief Reads a word of data from the given register. + + @note sfeTkIBus interface method + + @param devReg The device's register's address. + @param[out] data Data to read. + + @retval kSTkErrOk on success + */ + sfeTkError_t readRegisterWord(uint8_t devReg, uint16_t &data); + + /** + @brief Reads a block of data from the given register. + + @note sfeTkIBus interface method + @note This method is virtual to allow it to be overridden to support a device that requires a unique impl + + @param devReg The device's register's address. + @param[out] data Data buffer to read into + @param numBytes Number of bytes to read/length of data buffer + @param[out] readBytes - Number of bytes read + + + @retval kSTkErrOk on success + */ + sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes); + + /** + @brief Reads a block of data from the given 16-bit register address. + + @param reg The device's 16 bit register's address. + @param data Data buffer to read into + @param numBytes - Number of bytes to read/length of data buffer + @param[out] readBytes - number of bytes read + + @retval int returns kSTkErrOk on success, or kSTkErrFail code + + */ + sfeTkError_t readRegister16Region(uint16_t reg, uint8_t *data, size_t numBytes, size_t &readBytes); + + // Buffer size chunk getter/setter + /** + @brief set the buffer chunk size + + @note default size is 32 + + @param theChunk the new size - must be > 0 + + */ + void setBufferChunkSize(size_t theChunk) + { + if (theChunk > 0) + _bufferChunkSize = theChunk; + } + + /** + @brief set the buffer chunk size + + @retval The current chunk size + + */ + size_t bufferChunkSize(void) + { + return _bufferChunkSize; + } + + protected: + // note: The wire port is protected, allowing access if a sub-class is + // created to implement a special read/write routine + // + /** The actual Arduino i2c port */ + TwoWire *_i2cPort; + + private: + sfeTkError_t writeRegisterRegionAddress(uint8_t *devReg, size_t regLength, const uint8_t *data, size_t length); + + sfeTkError_t readRegisterRegionAnyAddress(uint8_t *devReg, size_t regLength, uint8_t *data, size_t numBytes, + size_t &readBytes); + + /** Default buffer chunk size*/ + static constexpr size_t kDefaultBufferChunk = 32; + + /** The I2C buffer chunker - chunk size*/ + size_t _bufferChunkSize; +}; diff --git a/src/sfeTkArdSPI.cpp b/src/sfeTkArdSPI.cpp new file mode 100644 index 0000000..15fcd60 --- /dev/null +++ b/src/sfeTkArdSPI.cpp @@ -0,0 +1,281 @@ + +// sfeTkArdSPI.cpp - Arduino SPI implementation for the toolkit + +/* +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#include "sfeTkArdSPI.h" +#include + +// Note: A leading "1" must be added to transfer with register to indicate a "read" +// Note to our future selves: +// This works / is required on both the ISM330 and MMC5983, +// but will cause badness with other SPI devices. +// We may need to add an alternate method if we ever add another SPI device. +#define kSPIReadBit 0x80 + +//--------------------------------------------------------------------------------- +// init() +// +// Arduino version of init. Will take in a defined SPI port/settings +// +sfeTkError_t sfeTkArdSPI::init(SPIClass &spiPort, SPISettings &busSPISettings, uint8_t csPin, bool bInit) +{ + // if we don't have a SPI port already + if (!_spiPort) + { + _spiPort = &spiPort; + + if (bInit) + _spiPort->begin(); + } + + setCS(csPin); + + // SPI settings are needed for every transaction + _sfeSPISettings = busSPISettings; + + return kSTkErrOk; +} + +//--------------------------------------------------------------------------------- +// init() +// +// Arduino version of init. +// +sfeTkError_t sfeTkArdSPI::init(uint8_t csPin, bool bInit) +{ + // If the transaction settings are not provided by the user they are built here. + SPISettings spiSettings = SPISettings(3000000, MSBFIRST, SPI_MODE3); + + // In addition of the port is not provided by the user, it defaults to SPI here. + return init(SPI, spiSettings, csPin, bInit); +} + +//--------------------------------------------------------------------------------- +// init() +// +// Arduino version of init. +// +sfeTkError_t sfeTkArdSPI::init(bool bInit) +{ + return init(cs(), bInit); +} + +//--------------------------------------------------------------------------------- +// writeRegisterByte() +// +// Writes a single byte to the device. +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::writeByte(uint8_t dataToWrite) +{ + + if (!_spiPort) + return kSTkErrBusNotInit; + + // Apply settings + _spiPort->beginTransaction(_sfeSPISettings); + // Signal communication start + digitalWrite(cs(), LOW); + + _spiPort->transfer(dataToWrite); + + // End communication + digitalWrite(cs(), HIGH); + _spiPort->endTransaction(); + + return kSTkErrOk; +} + +//--------------------------------------------------------------------------------- +// writeRegisterByte() +// +// Writes a byte to a given register. +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::writeRegisterByte(uint8_t devReg, uint8_t dataToWrite) +{ + + if (!_spiPort) + return kSTkErrBusNotInit; + + // Apply settings + _spiPort->beginTransaction(_sfeSPISettings); + // Signal communication start + digitalWrite(cs(), LOW); + + _spiPort->transfer(devReg); + _spiPort->transfer(dataToWrite); + + // End communication + digitalWrite(cs(), HIGH); + _spiPort->endTransaction(); + + return kSTkErrOk; +} + +//--------------------------------------------------------------------------------- +// writeRegisterWord() +// +// Writes a world to a given register. +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::writeRegisterWord(uint8_t devReg, uint16_t dataToWrite) +{ + return writeRegisterRegion(devReg, (uint8_t *)&dataToWrite, sizeof(uint8_t)) > 0; +} +//--------------------------------------------------------------------------------- +// writeRegisterRegion() +// +// Writes an array of bytes to a given register on the target address +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length) +{ + if (!_spiPort) + return kSTkErrBusNotInit; + + // Apply settings before work + _spiPort->beginTransaction(_sfeSPISettings); + + // Signal communication start + digitalWrite(cs(), LOW); + _spiPort->transfer(devReg); + + for (size_t i = 0; i < length; i++) + _spiPort->transfer(*data++); + + // End communication + digitalWrite(cs(), HIGH); + _spiPort->endTransaction(); + + return kSTkErrOk; +} + +// 16 bit address version ... +sfeTkError_t sfeTkArdSPI::writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length) +{ + if (!_spiPort) + return kSTkErrBusNotInit; + + // Apply settings before work + _spiPort->beginTransaction(_sfeSPISettings); + + // Signal communication start + digitalWrite(cs(), LOW); + _spiPort->transfer16(devReg); + + for (size_t i = 0; i < length; i++) + _spiPort->transfer(*data++); + + // End communication + digitalWrite(cs(), HIGH); + _spiPort->endTransaction(); + + return kSTkErrOk; +} + +sfeTkError_t sfeTkArdSPI::readRegisterByte(uint8_t devReg, uint8_t &data) +{ + size_t nRead; + sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(uint8_t), nRead); + + return (retval == kSTkErrOk && nRead == sizeof(uint8_t) ? kSTkErrOk : retval); +} + +sfeTkError_t sfeTkArdSPI::readRegisterWord(uint8_t devReg, uint16_t &data) +{ + size_t nRead; + sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(uint16_t), nRead); + + return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval); +} +//--------------------------------------------------------------------------------- +// readRegisterRegion() +// +// Reads an array of bytes to a given register on the target address +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) +{ + if (!_spiPort) + return kSTkErrBusNotInit; + + // Apply settings + _spiPort->beginTransaction(_sfeSPISettings); + + // Signal communication start + digitalWrite(cs(), LOW); + + // A leading "1" must be added to transfer with devRegister to indicate a "read" + _spiPort->transfer(devReg | kSPIReadBit); + + for (size_t i = 0; i < numBytes; i++) + *data++ = _spiPort->transfer(0x00); + + // End transaction + digitalWrite(cs(), HIGH); + _spiPort->endTransaction(); + + readBytes = numBytes; + + return kSTkErrOk; +} + +//--------------------------------------------------------------------------------- +// readRegister16Region() +// +// Reads an array of bytes to a given a 16 bit register on the target address +// +// Returns kSTkErrOk on success +// +sfeTkError_t sfeTkArdSPI::readRegister16Region(uint16_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) +{ + if (!_spiPort) + return kSTkErrBusNotInit; + + // Apply settings + _spiPort->beginTransaction(_sfeSPISettings); + + // Signal communication start + digitalWrite(cs(), LOW); + + // A leading "1" must be added to transfer with devRegister to indicate a "read" + _spiPort->transfer16(devReg | kSPIReadBit); + + for (size_t i = 0; i < numBytes; i++) + *data++ = _spiPort->transfer(0x00); + + // End transaction + digitalWrite(cs(), HIGH); + _spiPort->endTransaction(); + + readBytes = numBytes; + + return kSTkErrOk; +} \ No newline at end of file diff --git a/src/sfeTkArdSPI.h b/src/sfeTkArdSPI.h new file mode 100644 index 0000000..dcb3510 --- /dev/null +++ b/src/sfeTkArdSPI.h @@ -0,0 +1,192 @@ +// sfeTkBusSPI.h - Defines the Arduino SPI interface for the SparkFun Toolkit SDK + +#pragma once + +#include +#include + +/** + @brief This class implements the IBus interface for an SPI Implementation on Arduino + */ +class sfeTkArdSPI : public sfeTkISPI +{ + public: + /** + @brief Constructor for Arduino SPI bus object of the toolkit + */ + sfeTkArdSPI(void) : _spiPort(nullptr) + { + } + + /** + @brief Constructor for Arduino SPI bus object of the toolkit + + @param csPin The CS Pin for the device + */ + sfeTkArdSPI(uint8_t csPin) : sfeTkISPI(csPin) + { + } + /** + @brief Copy constructor for Arduino SPI bus object of the toolkit + + @param rhs source of the copy operation + */ + sfeTkArdSPI(sfeTkArdSPI const &rhs) : sfeTkISPI(), _spiPort{rhs._spiPort}, _sfeSPISettings{rhs._sfeSPISettings} + { + } + + /** + @brief Assignment copy operator for Arduino SPI bus object of the toolkit + + @param rhs The right hand side of the assignment. + @return sfeTkArdSPI& - The left hand side of the assignment. + */ + sfeTkArdSPI &operator=(const sfeTkArdSPI &rhs) + { + _spiPort = rhs._spiPort; + _sfeSPISettings = rhs._sfeSPISettings; + return *this; + } + + /** + @brief Method sets up the required SPI settings. + @note This function provides a default SPI Port. + + @param bInit Init the device - default is false. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t init(bool bInit = false); + + /** + @brief Method sets up the required SPI settings. + @note This function provides a default SPI Port. + + @param csPin The CS Pin for the device + @param bInit Init the device - default is false. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t init(uint8_t csPin, bool bInit = false); + + /** + @brief Method sets up the required SPI settings. + + @param spiPort Port for SPI communication. + @param busSPISettings Settings for speed, endianness, and spi mode of the SPI bus. + @param csPin The CS Pin for the device + @param bInit This flag tracks whether the bus has been initialized. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t init(SPIClass &spiPort, SPISettings &busSPISettings, uint8_t csPin, bool bInit = false); + + /** + @brief Write a single byte to the device + + @param data Data to write. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t writeByte(uint8_t data); + + /** + @brief Write a single byte to the given register + + @param devReg The device's register's address. + @param data Data to write. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t writeRegisterByte(uint8_t devReg, uint8_t data); + + /** + @brief Write a single word to the given register + + @param devReg The device's register's address. + @param data Data to write. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t writeRegisterWord(uint8_t devReg, uint16_t data); + + /** + @brief Writes a number of bytes starting at the given register's address. + @note This method is virtual to allow it to be overridden to support a device that requires a unique impl + + @param devReg The device's register's address. + @param data Data to write. + @param length - length of data + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length); + + /** + @brief Writes a number of bytes starting at the given register's address. + @note This method is virtual to allow it to be overridden to support a device that requires a unique impl + + @param devReg The device's register's address. + @param data Data to write. + @param length - length of data + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length); + + /** + @brief Read a single byte from the given register + + @param devReg The device's register's address. + @param[out] data Data to read. + + @retval sfeTkError_t - kSTkErrOk on success + */ + sfeTkError_t readRegisterByte(uint8_t devReg, uint8_t &data); + + /** + @brief read a single word to the given register + + @param devReg The device's register's address. + @param[out] data Data to write. + + @retval sfeTkError_t - true on success + */ + sfeTkError_t readRegisterWord(uint8_t devReg, uint16_t &data); + + /** + @brief Reads a block of data from the given register. + @note This method is virtual to allow it to be overridden to support a device that requires a unique impl + + @param reg The device's register's address. + @param[out] data Data buffer to read into + @param numBytes - length of data/size of data buffer + @param[out] readBytes - Number of bytes read + + @retval sfeTkError_t - true on success + */ + virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes); + + /** + @brief Reads a block of data from the given register. + @note This method is virtual to allow it to be overridden to support a device that requires a unique impl + + @param reg The device's register's 16 bit address. + @param[out] data Data buffer to read into + @param numBytes - Length of data to read/size of data buffer + @param[out] readBytes - Number of bytes read + + @retval sfeTkError_t - true on success + */ + virtual sfeTkError_t readRegister16Region(uint16_t reg, uint8_t *data, size_t numBytes, size_t &readBytes); + + protected: + // note: The instance data is protected, allowing access if a sub-class is + // created to implement a special read/write routine + // + /** Pointer to the spi port being used */ + SPIClass *_spiPort; + + /** This objects spi settings are used for every transaction. */ + SPISettings _sfeSPISettings; +}; From e0bc499ebfdfc82c74244bd141a9eb6c4de65507 Mon Sep 17 00:00:00 2001 From: santised Date: Wed, 29 May 2024 12:35:09 -0600 Subject: [PATCH 06/34] Removes unterminated comment --- examples/Example1_BasicReadings/Example1_BasicReadings.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index 934d386..c5bb5a3 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -12,7 +12,7 @@ * Copyright (c) 2024 SparkFun Electronics */ -#include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h"/* +#include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" // Create an ultrasonic sensor object QwiicUltrasonic myUltrasonic; From ee168f54a13c6938abf6260d613d05373a698f94 Mon Sep 17 00:00:00 2001 From: santised Date: Wed, 29 May 2024 12:38:34 -0600 Subject: [PATCH 07/34] Fixes missing include and indentation --- .../Example2_basic_distance_trigger.ino | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino b/examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino index 39d1339..0c989ae 100644 --- a/examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino +++ b/examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino @@ -11,6 +11,7 @@ * * Copyright (c) 2024 SparkFun Electronics */ +#include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" // Create an ultrasonic sensor object QwiicUltrasonic myUltrasonic; @@ -39,9 +40,9 @@ void setup() { // Attempt to begin the sensor if (myUltrasonic.begin(deviceAddress) == false) { - Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); - while(1) - ; + Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); + while(1) + ; } Serial.println("Ultrasonic sensor connected!"); From fe78ad5641a104b0c3ebdb7631be061ed18838a3 Mon Sep 17 00:00:00 2001 From: santised Date: Wed, 29 May 2024 12:41:48 -0600 Subject: [PATCH 08/34] Changes name of example 2 for camel case consistency --- .../Example2_BasicDistanceTrigger.ino} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino => Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino} (100%) diff --git a/examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino b/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino similarity index 100% rename from examples/Example2_basic_distance_trigger/Example2_basic_distance_trigger.ino rename to examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino From 89efacb82cae9c56385c64f4746171b75ab8507a Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 11:10:37 -0600 Subject: [PATCH 09/34] Uses the new writeBlock method, changes type for changeAddress function so that I can shift the address within --- .../Example3_ChangeAddress.ino | 4 +- src/sfeQwiicUltrasonic.cpp | 16 ++++-- src/sfeQwiicUltrasonic.h | 2 +- src/sfeTk/sfeTkIBus.h | 18 ++++++ src/sfeTkArdI2C.cpp | 57 ++++++++++++++++++- src/sfeTkArdI2C.h | 22 ++++++- 6 files changed, 109 insertions(+), 10 deletions(-) diff --git a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino index b45fa2f..8217410 100644 --- a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino +++ b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino @@ -25,7 +25,9 @@ QwiicUltrasonic myUltrasonic; // Example 2 to change the address to the new default. uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F // uint8_t deviceAddress = 0x00; -const uint8_t NEW_ADDR = 0x1E; + +// New addres is 7-bit unshifted. +uint8_t NEW_ADDR = 0x1E; void setup() { diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 28ddb75..aad03c7 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -1,9 +1,9 @@ -/* SparkFun Ulrasonic Distance Sensor - * - * Product: +/* SparkFun Ulrasonic Distance Sensor + * + * Product: * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) * * https://www.sparkfun.com/1XXXX - * + * * SPDX-License-Identifier: MIT * * Copyright (c) 2024 SparkFun Electronics @@ -80,16 +80,20 @@ sfeTkError_t sfeQwiicUltrasonic::getTriggeredDistance(uint16_t &distance) return kSTkErrOk; } -sfeTkError_t sfeQwiicUltrasonic::changeAddress(const uint8_t &address) +sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) { // Check whether the address is valid sfeTkError_t err; + size_t numBytes = 2; + address <<= 1; + const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, address}; if (address < kQwiicUltrasonicMinAddress || address > kQwiicUltrasonicMaxAddress) return kSTkErrFail; // Write the new address to the device. The first bit must be set to 1 - err = _theBus->writeRegisterByte(kUltrasonicAddressChangeCommand, (address<< 1)); + // err = _theBus->writeRegisterByte(kUltrasonicAddressChangeCommand, (address<< 1)); + err = _theBus->writeBlock(toWrite, numBytes); // Check whether the write was successful if (err != kSTkErrOk) diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index 99ca9f6..8270f1a 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -52,7 +52,7 @@ class sfeQwiicUltrasonic /// @brief Changes the I2C address of the Qwiic Ultrasonic sensor /// @param address New address, must be in the range 0x20 to 0x2F /// @return 0 for succuss, negative for errors, positive for warnings - sfeTkError_t changeAddress(const uint8_t &address); + sfeTkError_t changeAddress(uint8_t &address); /// @brief Gets the current I2C address being used by the library for the Qwiic Ultrasonic sensor /// @return The current I2C address, 7-bit unshifted diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h index 003a914..83c1cbd 100644 --- a/src/sfeTk/sfeTkIBus.h +++ b/src/sfeTk/sfeTkIBus.h @@ -95,6 +95,24 @@ class sfeTkIBus */ virtual sfeTkError_t writeByte(uint8_t data) = 0; + /**-------------------------------------------------------------------------- + * @brief Write a single byte to the device* + * @param data Data to write. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + * + */ + virtual sfeTkError_t writeWord(uint16_t data) = 0; + + /**-------------------------------------------------------------------------- + * @brief Write a single byte to the device* + * @param data Data to write. + * + * @retval sfeTkError_t - kSTkErrOk on successful execution. + * + */ + virtual sfeTkError_t writeBlock(const uint8_t *data, size_t length) = 0; + /**-------------------------------------------------------------------------- * @brief Write a single byte to the given register * diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp index 146ef19..6f94e5b 100644 --- a/src/sfeTkArdI2C.cpp +++ b/src/sfeTkArdI2C.cpp @@ -1,8 +1,28 @@ /* sfeTkArdI2C.cpp +The MIT License (MIT) + +Copyright (c) 2023 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: The +above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ #include "sfeTkArdI2C.h" +#include //--------------------------------------------------------------------------------- // init() @@ -68,7 +88,7 @@ sfeTkError_t sfeTkArdI2C::ping() //--------------------------------------------------------------------------------- // writeByte() // -// Writes a single byte to the device. +// Sends a single byte to the device. // // Returns true on success, false on failure // @@ -83,6 +103,41 @@ sfeTkError_t sfeTkArdI2C::writeByte(uint8_t dataToWrite) return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; } +//--------------------------------------------------------------------------------- +// writeWord() +// +// Sends a word to the device. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite) +{ + if (!_i2cPort) + return kSTkErrBusNotInit; + + return writeBlock((uint8_t *)&dataToWrite, sizeof(uint16_t)); +} + +//--------------------------------------------------------------------------------- +// writeBlock() +// +// Sends an array of data to the device. +// +// Returns true on success, false on failure +// +sfeTkError_t sfeTkArdI2C::writeBlock(const uint8_t *data, size_t length) +{ + int nData = 0; + if (!_i2cPort) + return kSTkErrBusNotInit; + + // do the Arduino I2C work + _i2cPort->beginTransmission(address()); + _i2cPort->write(data, (int)length); + + return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; +} + //--------------------------------------------------------------------------------- // writeRegisterByte() // diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h index f42837d..851f827 100644 --- a/src/sfeTkArdI2C.h +++ b/src/sfeTkArdI2C.h @@ -109,7 +109,7 @@ class sfeTkArdI2C : public sfeTkII2C sfeTkError_t ping(); /** - @brief Write a single byte to the device + @brief Sends a single byte to the device @note sfeTkIBus interface method @param data Data to write. @@ -118,6 +118,26 @@ class sfeTkArdI2C : public sfeTkII2C */ sfeTkError_t writeByte(uint8_t data); + /** + @brief Sends a word to the device. + @note sfeTkIBus interface method + + @param data Data to write. + + @retval returns kStkErrOk on success + */ + sfeTkError_t writeWord(uint16_t data); + + /** + @brief Sends a block of data to the device. + @note sfeTkIBus interface method + + @param data Data to write. + + @retval returns kStkErrOk on success + */ + sfeTkError_t writeBlock(const uint8_t *data, size_t length); + /** @brief Write a single byte to the given register @note sfeTkIBus interface method From 5131495159c9c6b39efdc628fc1dbeff748402f2 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 15:12:51 -0600 Subject: [PATCH 10/34] Removes bus files, adds bus files as submodule (may not work), adds workflow for compatibility with other microcontrollers --- .github/workflows/add_issue_to_project.yml | 16 + .github/workflows/compile-sketch.yml | 109 ++++++ .gitmodules | 3 + src/SparkFun_Toolkit.h | 37 --- src/sfeTk/sfeTkError.h | 64 ---- src/sfeTk/sfeTkIBus.h | 210 ------------ src/sfeTk/sfeTkII2C.h | 117 ------- src/sfeTk/sfeTkISPI.h | 90 ----- src/sfeTk/sfeToolkit.h | 32 -- src/sfeTkArdI2C.cpp | 367 --------------------- src/sfeTkArdI2C.h | 286 ---------------- src/sfeTkArdSPI.cpp | 281 ---------------- src/sfeTkArdSPI.h | 192 ----------- 13 files changed, 128 insertions(+), 1676 deletions(-) create mode 100644 .github/workflows/add_issue_to_project.yml create mode 100644 .github/workflows/compile-sketch.yml create mode 100644 .gitmodules delete mode 100644 src/SparkFun_Toolkit.h delete mode 100644 src/sfeTk/sfeTkError.h delete mode 100644 src/sfeTk/sfeTkIBus.h delete mode 100644 src/sfeTk/sfeTkII2C.h delete mode 100644 src/sfeTk/sfeTkISPI.h delete mode 100644 src/sfeTk/sfeToolkit.h delete mode 100644 src/sfeTkArdI2C.cpp delete mode 100644 src/sfeTkArdI2C.h delete mode 100644 src/sfeTkArdSPI.cpp delete mode 100644 src/sfeTkArdSPI.h diff --git a/.github/workflows/add_issue_to_project.yml b/.github/workflows/add_issue_to_project.yml new file mode 100644 index 0000000..aed806d --- /dev/null +++ b/.github/workflows/add_issue_to_project.yml @@ -0,0 +1,16 @@ +name: Add new issue to main project + +on: + issues: + types: + - opened + +jobs: + add-to-project: + name: Add issue to project + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@main + with: + project-url: https://github.com/orgs/sparkfun/projects/19 + github-token: ${{ secrets.DEFECT_ADD_TO_PROJECT }} diff --git a/.github/workflows/compile-sketch.yml b/.github/workflows/compile-sketch.yml new file mode 100644 index 0000000..bcc922a --- /dev/null +++ b/.github/workflows/compile-sketch.yml @@ -0,0 +1,109 @@ +name: Cross-compilation + +on: + - push + #- pull_request + + +jobs: + compile-sketch: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + board: + # Uno + # https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt + - fqbn: arduino:avr:mega + platforms: | + - name: arduino:avr + source-url: https://downloads.arduino.cc/packages/package_index.json + + # ESP32 + # https://github.com/espressif/arduino-esp32/blob/master/boards.txt + - fqbn: esp32:esp32:esp32 + platforms: | + - name: esp32:esp32 + source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + + # ESP32-S2 + # https://github.com/espressif/arduino-esp32/blob/master/boards.txt + - fqbn: esp32:esp32:esp32s2 + platforms: | + - name: esp32:esp32 + source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + + # ESP32-C3 + # https://github.com/espressif/arduino-esp32/blob/master/boards.txt + - fqbn: esp32:esp32:esp32c3 + platforms: | + - name: esp32:esp32 + source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + + # Artemis / Apollo3 + # https://github.com/sparkfun/Arduino_Apollo3/blob/main/boards.txt + - fqbn: SparkFun:apollo3:sfe_artemis_atp + platforms: | + - name: SparkFun:apollo3 + source-url: https://raw.githubusercontent.com/sparkfun/Arduino_Apollo3/master/package_sparkfun_apollo3_index.json + + # ESP8266 + # https://github.com/esp8266/Arduino/blob/master/boards.txt + - fqbn: esp8266:esp8266:thingdev + platforms: | + - name: esp8266:esp8266 + source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json + + # SAMD21 + # https://github.com/arduino/ArduinoCore-samd/blob/master/boards.txt + - fqbn: arduino:samd:mkr1000 + platforms: | + - name: arduino:samd + # source-url: https://downloads.arduino.cc/packages/package_index.json + + # Nano BLE 33 / nRF52840 + # https://github.com/arduino/ArduinoCore-mbed/blob/master/boards.txt + - fqbn: arduino:mbed:nano33ble + platforms: | + - name: arduino:mbed + # source-url: https://downloads.arduino.cc/packages/package_index.json + + # RP2040 + # https://github.com/arduino/ArduinoCore-mbed/blob/master/boards.txt + - fqbn: rp2040:rp2040:sparkfun_promicrorp2040 + platforms: | + - name: rp2040:rp2040 + source-url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json + + # STM32 + # https://github.com/arduino/ArduinoCore-mbed/blob/master/boards.txt + - fqbn: STMicroelectronics:stm32:GenF4 + platforms: | + - name: STMicroelectronics:stm32 + source-url: https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Branch name + run: echo running on branch ${GITHUB_REF##*/} + + - name: Compile Sketch + uses: arduino/compile-sketches@v1.1.0 + with: + platforms: ${{ matrix.board.platforms }} + fqbn: ${{ matrix.board.fqbn }} + libraries: | + - source-path: ./ + sketch-paths: | + - examples/Example1_BasicReadings + enable-warnings-report: true + enable-deltas-report: true + verbose: true + + # outputs: + # report-artifact-name: ${{ steps.report-artifact-name.outputs.report-artifact-name }} + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..922dfb6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/bus"] + path = src/bus + url = https://github.com/sparkfun/SparkFun_Toolkit.git diff --git a/src/SparkFun_Toolkit.h b/src/SparkFun_Toolkit.h deleted file mode 100644 index ffe3da6..0000000 --- a/src/SparkFun_Toolkit.h +++ /dev/null @@ -1,37 +0,0 @@ - -/* -SparkFun_Toolkit.h - -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#pragma once - -// Purpose: -// -// The SparkFun Toolkit provides a set of common implementations used throughout our (and others) -// Arduino Libraries. - -// Just include the toolkit headers - -#include -#include "sfeTkArdI2C.h" -#include "sfeTkArdSPI.h" \ No newline at end of file diff --git a/src/sfeTk/sfeTkError.h b/src/sfeTk/sfeTkError.h deleted file mode 100644 index 3f00841..0000000 --- a/src/sfeTk/sfeTkError.h +++ /dev/null @@ -1,64 +0,0 @@ - -// sfeTkError.h -// -// General header file for the SparkFun Toolkit -/* -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#pragma once - -#include - -/** - * General Concept - * A SparkFun Toolkit error system. The goal is to keep this simple. - * - * This mimics a variety of systems, using an int type for error codes, - * where: - * 0 = okay - * -1 = general failure - * >0 = an informative error - * - * Since *subsystems* in the toolkit can have their own errors, - * A start range for these errors are defined. Values > than this value - * define the errors for the set subsystem. These start ranges are set - * in this file, with actual error values defined in the the respective - * subsystem header files. - * - */ -typedef int32_t sfeTkError_t; - -// General errors - -/** - * @brief General error code for a failure. Note all errors are negative. - */ -const sfeTkError_t kSTkErrFail = -1; // general fail -/** - * @brief The error code value for success. This is always 0. - */ -const sfeTkError_t kSTkErrOk = 0; // success - -/** - * @brief A base value for bus errors. All bus errors are greater than this value, in the 1000 range - */ -const sfeTkError_t kSTkErrBaseBus = 0x1000; diff --git a/src/sfeTk/sfeTkIBus.h b/src/sfeTk/sfeTkIBus.h deleted file mode 100644 index 83c1cbd..0000000 --- a/src/sfeTk/sfeTkIBus.h +++ /dev/null @@ -1,210 +0,0 @@ - -// sfeTkIBus.h -// -// Defines the communication bus interface for the SparkFun Electronics Toolkit -> sfeTk -/* - -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#pragma once - -#include "sfeTkError.h" -#include - -/** - * @brief Define our error codes for the bus. Note Errors are negative, warnings/info positive, - * but keep the same increment on the base. - * - */ - -/** - * @brief Error code for when a bus system is not initalized. - */ -const sfeTkError_t kSTkErrBusNotInit = kSTkErrFail * (kSTkErrBaseBus + 1); - -/** - * @brief Returned when a bus system times out. - */ -const sfeTkError_t kSTkErrBusTimeout = kSTkErrFail * (kSTkErrBaseBus + 2); - -/** - * @brief Returned when a bus system does not respond. - */ -const sfeTkError_t kSTkErrBusNoResponse = kSTkErrFail * (kSTkErrBaseBus + 3); - -/** - * @brief Returned when the data to be sent is too long or recieved is too short. - */ -const sfeTkError_t kSTkErrBusDataTooLong = kSTkErrFail * (kSTkErrBaseBus + 4); - -/** - * @brief Returned when the bus settings are null, invalid or on set/initialised - */ -const sfeTkError_t kSTkErrBusNullSettings = kSTkErrFail * (kSTkErrBaseBus + 5); - -/** - * @brief Returned when the buffer is null or invalid. - */ -const sfeTkError_t kSTkErrBusNullBuffer = kSTkErrFail * (kSTkErrBaseBus + 6); - -/** - * @brief Returned when the bus is under read. Warning - */ -const sfeTkError_t kSTkErrBusUnderRead = kSTkErrBaseBus + 7; - -/** - * @brief Returned when the bus is not enabled. Warning - */ -const sfeTkError_t kSTkErrBusNotEnabled = kSTkErrBaseBus + 8; - -/** - * @brief Interface that defines the communication bus for the SparkFun Electronics Toolkit. - * - * The bus interface defines the basic methods for reading and writing data to a device. Specific - * bus implementations will extend this interface to provide the necessary functionality for the - * desired bus type. - */ -class sfeTkIBus -{ - public: - /**-------------------------------------------------------------------------- - * @brief Write a single byte to the device* - * @param data Data to write. - * - * @retval sfeTkError_t - kSTkErrOk on successful execution. - * - */ - virtual sfeTkError_t writeByte(uint8_t data) = 0; - - /**-------------------------------------------------------------------------- - * @brief Write a single byte to the device* - * @param data Data to write. - * - * @retval sfeTkError_t - kSTkErrOk on successful execution. - * - */ - virtual sfeTkError_t writeWord(uint16_t data) = 0; - - /**-------------------------------------------------------------------------- - * @brief Write a single byte to the device* - * @param data Data to write. - * - * @retval sfeTkError_t - kSTkErrOk on successful execution. - * - */ - virtual sfeTkError_t writeBlock(const uint8_t *data, size_t length) = 0; - - /**-------------------------------------------------------------------------- - * @brief Write a single byte to the given register - * - * @param devReg The device's register's address. - * @param data Data to write. - * - * @retval sfeTkError_t - kSTkErrOk on successful execution. - * - */ - virtual sfeTkError_t writeRegisterByte(uint8_t devReg, uint8_t data) = 0; - - /**-------------------------------------------------------------------------- - * @brief Write a single word (16 bit) to the given register - * - * @param devReg The device's register's address. - * @param data Data to write. - * - * @retval sfeTkError_t - kSTkErrOk on successful execution. - * - */ - virtual sfeTkError_t writeRegisterWord(uint8_t devReg, uint16_t data) = 0; - - /**-------------------------------------------------------------------------- - * @brief Writes a number of bytes starting at the given register's address. - * - * @param devReg The device's register's address. - * @param data Data to write. - * @param length - length of data - * - * @retval sfeTkError_t kSTkErrOk on successful execution - * - */ - virtual sfeTkError_t writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length) = 0; - - /**-------------------------------------------------------------------------- - * @brief Writes a number of bytes starting at the given register's 16-bit address. - * - * @param devReg The device's register's address. - * @param data Data to write. - * @param length - length of data - * - * @retval sfeTkError_t kSTkErrOk on successful execution - * - */ - virtual sfeTkError_t writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length) = 0; - - /**-------------------------------------------------------------------------- - * @brief Read a single byte from the given register - * - * @param devReg The device's register's address. - * @param data Data to read. - * - * @retval sfeTkError_t - kSTkErrOk on successful execution. - * - */ - virtual sfeTkError_t readRegisterByte(uint8_t devReg, uint8_t &data) = 0; - - /**-------------------------------------------------------------------------- - * @brief Read a single word (16 bit) from the given register - * - * @param devReg The device's register's address. - * @param data Data to read. - * - * @retval sfeTkError_t - kSTkErrOk on successful execution. - */ - virtual sfeTkError_t readRegisterWord(uint8_t devReg, uint16_t &data) = 0; - - /**-------------------------------------------------------------------------- - * @brief Reads a block of data from the given register. - * - * @param reg The device's register's address. - * @param data Data to write. - * @param numBytes - length of data - * @param[out] readBytes - number of bytes read - * - * @retval int returns kSTkErrOk on success, or kSTkErrFail code - * - */ - virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes) = 0; - - /**-------------------------------------------------------------------------- - * @brief Reads a block of data from the given 16-bit register address. - * - * @param reg The device's 16 bit register's address. - * @param data Data to write. - * @param numBytes - length of data - * @param[out] readBytes - number of bytes read - * - * @retval int returns kSTkErrOk on success, or kSTkErrFail code - * - */ - virtual sfeTkError_t readRegister16Region(uint16_t reg, uint8_t *data, size_t numBytes, size_t &readBytes) = 0; -}; - -//}; diff --git a/src/sfeTk/sfeTkII2C.h b/src/sfeTk/sfeTkII2C.h deleted file mode 100644 index f9fdf57..0000000 --- a/src/sfeTk/sfeTkII2C.h +++ /dev/null @@ -1,117 +0,0 @@ - -// sfeTkII2C.h -// -// Defines the I2C communication bus interface for the SparkFun Electronics Toolkit -/* -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#pragma once - -#include "sfeTkIBus.h" - -/** - * @brief Interface that defines the I2C communication bus for the SparkFun Electronics Toolkit. - * - * The I2C bus interface extends the IBus interface and adds the ability to set and get the I2C - * address and stop flag. - */ -class sfeTkII2C : public sfeTkIBus -{ - public: - // set the address to No address and stop flag to true - /** - * @brief Constructor for the I2C bus - */ - sfeTkII2C() : _address{kNoAddress}, _stop{true} - { - } - /** - * @brief Constructor for the I2C bus with an address passed in - * - * @param addr - */ - sfeTkII2C(uint8_t addr) : _address{addr} - { - } - - /**-------------------------------------------------------------------------- - @brief A simple ping of the device at the set address - - @retval sfeTkError_t - ok on success - - */ - virtual sfeTkError_t ping() = 0; - - /**-------------------------------------------------------------------------- - @brief setter for the I2C address - - @param devAddr The device's address - - */ - virtual void setAddress(uint8_t devAddr) - { - _address = devAddr; - } - - /**-------------------------------------------------------------------------- - @brief getter for the I2C address - - @retval uint8_t returns the address for the device - - */ - virtual uint8_t address(void) - { - return _address; - } - - /**-------------------------------------------------------------------------- - @brief setter for I2C stop message (vs restarts) - - @param stop The value to set for "send stop" - */ - virtual void setStop(bool stop) - { - _stop = stop; - } - - /**-------------------------------------------------------------------------- - @brief getter for I2C stops message (vs restarts) - - @retval bool returns the value of "send stop" - - */ - virtual bool stop(void) - { - return _stop; - } - - /** - * @brief kNoAddress is a constant to indicate no address has been set - */ - static constexpr uint8_t kNoAddress = 0; - - private: - uint8_t _address; - bool _stop; -}; - -//}; diff --git a/src/sfeTk/sfeTkISPI.h b/src/sfeTk/sfeTkISPI.h deleted file mode 100644 index e9df115..0000000 --- a/src/sfeTk/sfeTkISPI.h +++ /dev/null @@ -1,90 +0,0 @@ - -// sfeTkISPI.h -// -// Defines the SPI communication bus interface for the SparkFun Electronics Toolkit -/* - -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#pragma once - -#include "sfeTkIBus.h" - -/** - * @brief Interface that defines the SPI communication bus for the SparkFun Electronics Toolkit. - * - * The SPI bus interface extends the IBus interface and adds the ability to set and get the CS pin. - */ -class sfeTkISPI : public sfeTkIBus -{ - public: - /**-------------------------------------------------------------------------- - @brief Constructor for the SPI bus - - */ - sfeTkISPI() : _cs{kNoCSPin} - { - } - - /**-------------------------------------------------------------------------- - @brief Constructor for the SPI bus - - @param csPin The CS Pin for the device - - */ - sfeTkISPI(uint8_t csPin) : _cs{csPin} - { - } - - /**-------------------------------------------------------------------------- - @brief setter for the CS Pin - - @param devCS The device's CS Pin - - */ - virtual void setCS(uint8_t devCS) - { - _cs = devCS; - } - - /**-------------------------------------------------------------------------- - @brief getter for the cs pin - - @retval uint8_t returns the CS pin for the device - - */ - virtual uint8_t cs(void) - { - return _cs; - } - - /**-------------------------------------------------------------------------- - @brief A constant for no CS pin - */ - static constexpr uint8_t kNoCSPin = 0; - - private: - /** The internal storage of the _cs value*/ - uint8_t _cs; -}; - -//}; diff --git a/src/sfeTk/sfeToolkit.h b/src/sfeTk/sfeToolkit.h deleted file mode 100644 index da1ec00..0000000 --- a/src/sfeTk/sfeToolkit.h +++ /dev/null @@ -1,32 +0,0 @@ - -// sfeToolkit.h -// -// General header file for the SparkFun Toolkit -/* - -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#pragma once - -/** - @brief Common include file for the core of the SparkFun Electronics Toolkit -*/ -#include "sfeTkError.h" diff --git a/src/sfeTkArdI2C.cpp b/src/sfeTkArdI2C.cpp deleted file mode 100644 index 6f94e5b..0000000 --- a/src/sfeTkArdI2C.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/* -sfeTkArdI2C.cpp -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include "sfeTkArdI2C.h" -#include - -//--------------------------------------------------------------------------------- -// init() -// -// Arduino version of init - pass in already setup wire port ... -// -sfeTkError_t sfeTkArdI2C::init(TwoWire &wirePort, uint8_t addr, bool bInit) -{ - // if we don't have a wire port already - if (!_i2cPort) - { - // use the pass in port - _i2cPort = &wirePort; - - if (bInit) - _i2cPort->begin(); - } - - setAddress(addr); - return kSTkErrOk; -} - -//--------------------------------------------------------------------------------- -// init() -// -// no parameters version of init. Setups a a wire port if needed. -// -sfeTkError_t sfeTkArdI2C::init(uint8_t addr) -{ - // no port yet, do the default version of it - if (!_i2cPort) - return init(Wire, addr); - - // We have a port, so arcady init'd - right? - return kSTkErrOk; -} - -//--------------------------------------------------------------------------------- -// init() -// -// no parameters version of init. Setups a a wire port if needed. -// -sfeTkError_t sfeTkArdI2C::init(void) -{ - // call with our currently set address ... - return init(address()); -} -//--------------------------------------------------------------------------------- -// ping() -// -// Ping an I2C address to see if something is there. -// -sfeTkError_t sfeTkArdI2C::ping() -{ - // no port, no - if (!_i2cPort) - return kSTkErrBusNotInit; - - _i2cPort->beginTransmission(address()); - return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; -} - -//--------------------------------------------------------------------------------- -// writeByte() -// -// Sends a single byte to the device. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::writeByte(uint8_t dataToWrite) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - // do the Arduino I2C work - _i2cPort->beginTransmission(address()); - _i2cPort->write(dataToWrite); - return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; -} - -//--------------------------------------------------------------------------------- -// writeWord() -// -// Sends a word to the device. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::writeWord(uint16_t dataToWrite) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - return writeBlock((uint8_t *)&dataToWrite, sizeof(uint16_t)); -} - -//--------------------------------------------------------------------------------- -// writeBlock() -// -// Sends an array of data to the device. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::writeBlock(const uint8_t *data, size_t length) -{ - int nData = 0; - if (!_i2cPort) - return kSTkErrBusNotInit; - - // do the Arduino I2C work - _i2cPort->beginTransmission(address()); - _i2cPort->write(data, (int)length); - - return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; -} - -//--------------------------------------------------------------------------------- -// writeRegisterByte() -// -// Writes a byte to a given register. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::writeRegisterByte(uint8_t devReg, uint8_t dataToWrite) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - // do the Arduino I2C work - _i2cPort->beginTransmission(address()); - _i2cPort->write(devReg); - _i2cPort->write(dataToWrite); - return _i2cPort->endTransmission() == 0 ? kSTkErrOk : kSTkErrFail; -} - -//--------------------------------------------------------------------------------- -// writeRegisterWord() -// -// Writes a word to a given register. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::writeRegisterWord(uint8_t devReg, uint16_t dataToWrite) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - return writeRegisterRegion(devReg, (uint8_t *)&dataToWrite, sizeof(uint16_t)); -} - -/** - * @brief Writes an array of bytes to a register on the target address. Supports any address size - * - * @param devReg The device's register's address - can be any size - * @param regLength The length of the register address - * @param data The data to write - * @param length The length of the data buffer - * @return sfeTkError_t Returns kSTkErrOk on success, or kSTkErrFail code - */ -sfeTkError_t sfeTkArdI2C::writeRegisterRegionAddress(uint8_t *devReg, size_t regLength, const uint8_t *data, - size_t length) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - _i2cPort->beginTransmission(address()); - _i2cPort->write(devReg, regLength); - _i2cPort->write(data, (int)length); - - return _i2cPort->endTransmission() ? kSTkErrFail : kSTkErrOk; -} - -//--------------------------------------------------------------------------------- -// writeRegisterRegion() -// -// Writes an array of bytes to a given register on the target address -// -// Returns the number of bytes written, < 0 is an error -// -sfeTkError_t sfeTkArdI2C::writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length) -{ - return writeRegisterRegionAddress(&devReg, 1, data, length); -} - -//--------------------------------------------------------------------------------- -// write16BitRegisterRegion() -// -// Writes an array of bytes to a given 16-bit register on the target address -// -// Returns the number of bytes written, < 0 is an error -// -sfeTkError_t sfeTkArdI2C::writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length) -{ - devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff); - return writeRegisterRegionAddress((uint8_t *)&devReg, 2, data, length); -} - -//--------------------------------------------------------------------------------- - -/** - * @brief Reads an array of bytes to a register on the target address. Supports any address size - * - * @param devReg The device's register's address - can be any size - * @param regLength The length of the register address - * @param data The data to buffer to read into - * @param numBytes The length of the data buffer - * @param readBytes[out] The number of bytes read - * @return sfeTkError_t Returns kSTkErrOk on success, or kSTkErrFail code - */ -sfeTkError_t sfeTkArdI2C::readRegisterRegionAnyAddress(uint8_t *devReg, size_t regLength, uint8_t *data, - size_t numBytes, size_t &readBytes) -{ - - // got port - if (!_i2cPort) - return kSTkErrBusNotInit; - - // Buffer valid? - if (!data) - return kSTkErrBusNullBuffer; - - readBytes = 0; - - uint16_t nOrig = numBytes; // original number of bytes. - uint8_t nChunk; - uint16_t nReturned; - uint16_t i; // counter in loop - bool bFirstInter = true; // Flag for first iteration - used to send devRegister - - while (numBytes > 0) - { - if (bFirstInter) - { - _i2cPort->beginTransmission(address()); - - _i2cPort->write(devReg, regLength); - - if (_i2cPort->endTransmission(stop()) != 0) - return kSTkErrFail; // error with the end transmission - - bFirstInter = false; - } - - // We're chunking in data - keeping the max chunk to kMaxI2CBufferLength - nChunk = numBytes > _bufferChunkSize ? _bufferChunkSize : numBytes; - - // Request the bytes. If this is the last chunk, always send a stop - nReturned = _i2cPort->requestFrom((int)address(), (int)nChunk, (int)(nChunk == numBytes ? true : stop())); - - // No data returned, no dice - if (nReturned == 0) - return kSTkErrBusUnderRead; // error - - // Copy the retrieved data chunk to the current index in the data segment - for (i = 0; i < nReturned; i++) - *data++ = _i2cPort->read(); - - // Decrement the amount of data received from the overall data request amount - numBytes = numBytes - nReturned; - - } // end while - - readBytes = nOrig - numBytes; // Bytes read. - - return (readBytes == nOrig) ? kSTkErrOk : kSTkErrBusUnderRead; // Success -} - -//--------------------------------------------------------------------------------- -// readRegisterByte() -// -// Reads a byte to a given register. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::readRegisterByte(uint8_t devReg, uint8_t &dataToRead) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - // Return value - uint8_t result = 0; - - int nData = 0; - - _i2cPort->beginTransmission(address()); - _i2cPort->write(devReg); - _i2cPort->endTransmission(stop()); - _i2cPort->requestFrom(address(), (uint8_t)1); - - while (_i2cPort->available()) // slave may send less than requested - { - result = _i2cPort->read(); // receive a byte as a proper uint8_t - nData++; - } - - if (nData == sizeof(uint8_t)) // Only update outputPointer if a single byte was returned - dataToRead = result; - - return (nData == sizeof(uint8_t) ? kSTkErrOk : kSTkErrFail); -} - -//--------------------------------------------------------------------------------- -// readRegisterWord() -// -// Reads a word to a given register. -// -// Returns true on success, false on failure -// -sfeTkError_t sfeTkArdI2C::readRegisterWord(uint8_t devReg, uint16_t &dataToRead) -{ - if (!_i2cPort) - return kSTkErrBusNotInit; - - size_t nRead; - sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&dataToRead, sizeof(uint16_t), nRead); - - return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval); -} - -//--------------------------------------------------------------------------------- -// readRegisterRegion() -// -// Reads an array of bytes to a given register on the target address -// -// Returns the number of bytes read, < 0 is an error -// -sfeTkError_t sfeTkArdI2C::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) -{ - return readRegisterRegionAnyAddress(&devReg, 1, data, numBytes, readBytes); -} - -//--------------------------------------------------------------------------------- -// read16BitRegisterRegion() -// -// Reads an array of bytes to a given 16-bit register on the target address -// -// Returns the number of bytes read, < 0 is an error -// -sfeTkError_t sfeTkArdI2C::readRegister16Region(uint16_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) -{ - devReg = ((devReg << 8) & 0xff00) | ((devReg >> 8) & 0x00ff); - return readRegisterRegionAnyAddress((uint8_t *)&devReg, 2, data, numBytes, readBytes); -} diff --git a/src/sfeTkArdI2C.h b/src/sfeTkArdI2C.h deleted file mode 100644 index 851f827..0000000 --- a/src/sfeTkArdI2C.h +++ /dev/null @@ -1,286 +0,0 @@ -/* -sfeTkArdI2c.h - -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -The following classes specify the behavior for communicating -over Inter-Integrated Circuit (I2C) in Arduino - -*/ - -#pragma once - -#include -#include - -// Include our platform I2C interface definition. -#include - -/** - * @brief The sfeTkArdI2C implements an sfeTkII2C interface, defining the Arduino implementation for I2C in the Toolkit - */ - -class sfeTkArdI2C : public sfeTkII2C -{ - public: - /** - @brief Constructor - */ - sfeTkArdI2C(void) : _i2cPort(nullptr), _bufferChunkSize{kDefaultBufferChunk} - { - } - /** - @brief Constructor - - @param addr The address of the device - */ - sfeTkArdI2C(uint8_t addr) : sfeTkII2C(addr) - { - } - - /** - * @brief copy constructor - */ - sfeTkArdI2C(sfeTkArdI2C const &rhs) : sfeTkII2C(), _i2cPort{rhs._i2cPort} - { - } - - /** - * @brief Copy assignment - * - * @param rhs right hand side of the assignment - * @return value of the left hand side of the assignment - */ - sfeTkArdI2C &operator=(const sfeTkArdI2C &rhs) - { - _i2cPort = rhs._i2cPort; - return *this; - } - - /** - @brief Method sets up the required I2C settings. - @note This function provides a default I2C Port. - - @retval kSTkErrOk on successful execution. - */ - sfeTkError_t init(); - - /** - @brief - address version of the init method - - @param addr The address of the device - */ - sfeTkError_t init(uint8_t addr); - - /** - @brief Method sets up the required I2C settings. - - @param wirePort Port for I2C communication. - @param addr The address of the device - @param bInit This flag tracks whether the bus has been initialized. - - @retval kSTkErrOk on successful execution. - */ - sfeTkError_t init(TwoWire &wirePort, uint8_t addr, bool bInit = false); - - /** - @brief A simple ping of the device at the given address. - @note sfeTkIBus interface method - - @retval kSTkErrOk on success, - */ - sfeTkError_t ping(); - - /** - @brief Sends a single byte to the device - @note sfeTkIBus interface method - - @param data Data to write. - - @retval returns kStkErrOk on success - */ - sfeTkError_t writeByte(uint8_t data); - - /** - @brief Sends a word to the device. - @note sfeTkIBus interface method - - @param data Data to write. - - @retval returns kStkErrOk on success - */ - sfeTkError_t writeWord(uint16_t data); - - /** - @brief Sends a block of data to the device. - @note sfeTkIBus interface method - - @param data Data to write. - - @retval returns kStkErrOk on success - */ - sfeTkError_t writeBlock(const uint8_t *data, size_t length); - - /** - @brief Write a single byte to the given register - @note sfeTkIBus interface method - - @param devReg The device's register's address. - @param data Data to write. - - @retval returns kStkErrOk on success - */ - sfeTkError_t writeRegisterByte(uint8_t devReg, uint8_t data); - - /** - @brief Write a single word to the given register - @note sfeTkIBus interface method - - @param devReg The device's register's address. - @param data Data to write. - - @retval returns kStkErrOk on success - */ - sfeTkError_t writeRegisterWord(uint8_t devReg, uint16_t data); - - /** - @brief Writes a number of bytes starting at the given register's address. - - @note sfeTkIBus interface method - @note This method is virtual to allow it to be overridden to support a device that requires a unique impl - - @param devReg The device's register's address. - @param data Data to write. - @param length - length of data - - @retval kStkErrOk on success - */ - sfeTkError_t writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length); - - /** - @brief Writes a number of bytes starting at the given register's 16-bit address. - - @param devReg The device's register's address - 16 bit. - @param data Data to write. - @param length - length of data - - @retval sfeTkError_t kSTkErrOk on successful execution - - */ - sfeTkError_t writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length); - - /** - @brief Reads a byte of data from the given register. - - @note sfeTkIBus interface method - - @param devReg The device's register's address. - @param[out] data Data to read. - - @retval kStkErrOk on success - */ - sfeTkError_t readRegisterByte(uint8_t devReg, uint8_t &data); - - /** - @brief Reads a word of data from the given register. - - @note sfeTkIBus interface method - - @param devReg The device's register's address. - @param[out] data Data to read. - - @retval kSTkErrOk on success - */ - sfeTkError_t readRegisterWord(uint8_t devReg, uint16_t &data); - - /** - @brief Reads a block of data from the given register. - - @note sfeTkIBus interface method - @note This method is virtual to allow it to be overridden to support a device that requires a unique impl - - @param devReg The device's register's address. - @param[out] data Data buffer to read into - @param numBytes Number of bytes to read/length of data buffer - @param[out] readBytes - Number of bytes read - - - @retval kSTkErrOk on success - */ - sfeTkError_t readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes); - - /** - @brief Reads a block of data from the given 16-bit register address. - - @param reg The device's 16 bit register's address. - @param data Data buffer to read into - @param numBytes - Number of bytes to read/length of data buffer - @param[out] readBytes - number of bytes read - - @retval int returns kSTkErrOk on success, or kSTkErrFail code - - */ - sfeTkError_t readRegister16Region(uint16_t reg, uint8_t *data, size_t numBytes, size_t &readBytes); - - // Buffer size chunk getter/setter - /** - @brief set the buffer chunk size - - @note default size is 32 - - @param theChunk the new size - must be > 0 - - */ - void setBufferChunkSize(size_t theChunk) - { - if (theChunk > 0) - _bufferChunkSize = theChunk; - } - - /** - @brief set the buffer chunk size - - @retval The current chunk size - - */ - size_t bufferChunkSize(void) - { - return _bufferChunkSize; - } - - protected: - // note: The wire port is protected, allowing access if a sub-class is - // created to implement a special read/write routine - // - /** The actual Arduino i2c port */ - TwoWire *_i2cPort; - - private: - sfeTkError_t writeRegisterRegionAddress(uint8_t *devReg, size_t regLength, const uint8_t *data, size_t length); - - sfeTkError_t readRegisterRegionAnyAddress(uint8_t *devReg, size_t regLength, uint8_t *data, size_t numBytes, - size_t &readBytes); - - /** Default buffer chunk size*/ - static constexpr size_t kDefaultBufferChunk = 32; - - /** The I2C buffer chunker - chunk size*/ - size_t _bufferChunkSize; -}; diff --git a/src/sfeTkArdSPI.cpp b/src/sfeTkArdSPI.cpp deleted file mode 100644 index 15fcd60..0000000 --- a/src/sfeTkArdSPI.cpp +++ /dev/null @@ -1,281 +0,0 @@ - -// sfeTkArdSPI.cpp - Arduino SPI implementation for the toolkit - -/* -The MIT License (MIT) - -Copyright (c) 2023 SparkFun Electronics - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: The -above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED -"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include "sfeTkArdSPI.h" -#include - -// Note: A leading "1" must be added to transfer with register to indicate a "read" -// Note to our future selves: -// This works / is required on both the ISM330 and MMC5983, -// but will cause badness with other SPI devices. -// We may need to add an alternate method if we ever add another SPI device. -#define kSPIReadBit 0x80 - -//--------------------------------------------------------------------------------- -// init() -// -// Arduino version of init. Will take in a defined SPI port/settings -// -sfeTkError_t sfeTkArdSPI::init(SPIClass &spiPort, SPISettings &busSPISettings, uint8_t csPin, bool bInit) -{ - // if we don't have a SPI port already - if (!_spiPort) - { - _spiPort = &spiPort; - - if (bInit) - _spiPort->begin(); - } - - setCS(csPin); - - // SPI settings are needed for every transaction - _sfeSPISettings = busSPISettings; - - return kSTkErrOk; -} - -//--------------------------------------------------------------------------------- -// init() -// -// Arduino version of init. -// -sfeTkError_t sfeTkArdSPI::init(uint8_t csPin, bool bInit) -{ - // If the transaction settings are not provided by the user they are built here. - SPISettings spiSettings = SPISettings(3000000, MSBFIRST, SPI_MODE3); - - // In addition of the port is not provided by the user, it defaults to SPI here. - return init(SPI, spiSettings, csPin, bInit); -} - -//--------------------------------------------------------------------------------- -// init() -// -// Arduino version of init. -// -sfeTkError_t sfeTkArdSPI::init(bool bInit) -{ - return init(cs(), bInit); -} - -//--------------------------------------------------------------------------------- -// writeRegisterByte() -// -// Writes a single byte to the device. -// -// Returns kSTkErrOk on success -// -sfeTkError_t sfeTkArdSPI::writeByte(uint8_t dataToWrite) -{ - - if (!_spiPort) - return kSTkErrBusNotInit; - - // Apply settings - _spiPort->beginTransaction(_sfeSPISettings); - // Signal communication start - digitalWrite(cs(), LOW); - - _spiPort->transfer(dataToWrite); - - // End communication - digitalWrite(cs(), HIGH); - _spiPort->endTransaction(); - - return kSTkErrOk; -} - -//--------------------------------------------------------------------------------- -// writeRegisterByte() -// -// Writes a byte to a given register. -// -// Returns kSTkErrOk on success -// -sfeTkError_t sfeTkArdSPI::writeRegisterByte(uint8_t devReg, uint8_t dataToWrite) -{ - - if (!_spiPort) - return kSTkErrBusNotInit; - - // Apply settings - _spiPort->beginTransaction(_sfeSPISettings); - // Signal communication start - digitalWrite(cs(), LOW); - - _spiPort->transfer(devReg); - _spiPort->transfer(dataToWrite); - - // End communication - digitalWrite(cs(), HIGH); - _spiPort->endTransaction(); - - return kSTkErrOk; -} - -//--------------------------------------------------------------------------------- -// writeRegisterWord() -// -// Writes a world to a given register. -// -// Returns kSTkErrOk on success -// -sfeTkError_t sfeTkArdSPI::writeRegisterWord(uint8_t devReg, uint16_t dataToWrite) -{ - return writeRegisterRegion(devReg, (uint8_t *)&dataToWrite, sizeof(uint8_t)) > 0; -} -//--------------------------------------------------------------------------------- -// writeRegisterRegion() -// -// Writes an array of bytes to a given register on the target address -// -// Returns kSTkErrOk on success -// -sfeTkError_t sfeTkArdSPI::writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length) -{ - if (!_spiPort) - return kSTkErrBusNotInit; - - // Apply settings before work - _spiPort->beginTransaction(_sfeSPISettings); - - // Signal communication start - digitalWrite(cs(), LOW); - _spiPort->transfer(devReg); - - for (size_t i = 0; i < length; i++) - _spiPort->transfer(*data++); - - // End communication - digitalWrite(cs(), HIGH); - _spiPort->endTransaction(); - - return kSTkErrOk; -} - -// 16 bit address version ... -sfeTkError_t sfeTkArdSPI::writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length) -{ - if (!_spiPort) - return kSTkErrBusNotInit; - - // Apply settings before work - _spiPort->beginTransaction(_sfeSPISettings); - - // Signal communication start - digitalWrite(cs(), LOW); - _spiPort->transfer16(devReg); - - for (size_t i = 0; i < length; i++) - _spiPort->transfer(*data++); - - // End communication - digitalWrite(cs(), HIGH); - _spiPort->endTransaction(); - - return kSTkErrOk; -} - -sfeTkError_t sfeTkArdSPI::readRegisterByte(uint8_t devReg, uint8_t &data) -{ - size_t nRead; - sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(uint8_t), nRead); - - return (retval == kSTkErrOk && nRead == sizeof(uint8_t) ? kSTkErrOk : retval); -} - -sfeTkError_t sfeTkArdSPI::readRegisterWord(uint8_t devReg, uint16_t &data) -{ - size_t nRead; - sfeTkError_t retval = readRegisterRegion(devReg, (uint8_t *)&data, sizeof(uint16_t), nRead); - - return (retval == kSTkErrOk && nRead == sizeof(uint16_t) ? kSTkErrOk : retval); -} -//--------------------------------------------------------------------------------- -// readRegisterRegion() -// -// Reads an array of bytes to a given register on the target address -// -// Returns kSTkErrOk on success -// -sfeTkError_t sfeTkArdSPI::readRegisterRegion(uint8_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) -{ - if (!_spiPort) - return kSTkErrBusNotInit; - - // Apply settings - _spiPort->beginTransaction(_sfeSPISettings); - - // Signal communication start - digitalWrite(cs(), LOW); - - // A leading "1" must be added to transfer with devRegister to indicate a "read" - _spiPort->transfer(devReg | kSPIReadBit); - - for (size_t i = 0; i < numBytes; i++) - *data++ = _spiPort->transfer(0x00); - - // End transaction - digitalWrite(cs(), HIGH); - _spiPort->endTransaction(); - - readBytes = numBytes; - - return kSTkErrOk; -} - -//--------------------------------------------------------------------------------- -// readRegister16Region() -// -// Reads an array of bytes to a given a 16 bit register on the target address -// -// Returns kSTkErrOk on success -// -sfeTkError_t sfeTkArdSPI::readRegister16Region(uint16_t devReg, uint8_t *data, size_t numBytes, size_t &readBytes) -{ - if (!_spiPort) - return kSTkErrBusNotInit; - - // Apply settings - _spiPort->beginTransaction(_sfeSPISettings); - - // Signal communication start - digitalWrite(cs(), LOW); - - // A leading "1" must be added to transfer with devRegister to indicate a "read" - _spiPort->transfer16(devReg | kSPIReadBit); - - for (size_t i = 0; i < numBytes; i++) - *data++ = _spiPort->transfer(0x00); - - // End transaction - digitalWrite(cs(), HIGH); - _spiPort->endTransaction(); - - readBytes = numBytes; - - return kSTkErrOk; -} \ No newline at end of file diff --git a/src/sfeTkArdSPI.h b/src/sfeTkArdSPI.h deleted file mode 100644 index dcb3510..0000000 --- a/src/sfeTkArdSPI.h +++ /dev/null @@ -1,192 +0,0 @@ -// sfeTkBusSPI.h - Defines the Arduino SPI interface for the SparkFun Toolkit SDK - -#pragma once - -#include -#include - -/** - @brief This class implements the IBus interface for an SPI Implementation on Arduino - */ -class sfeTkArdSPI : public sfeTkISPI -{ - public: - /** - @brief Constructor for Arduino SPI bus object of the toolkit - */ - sfeTkArdSPI(void) : _spiPort(nullptr) - { - } - - /** - @brief Constructor for Arduino SPI bus object of the toolkit - - @param csPin The CS Pin for the device - */ - sfeTkArdSPI(uint8_t csPin) : sfeTkISPI(csPin) - { - } - /** - @brief Copy constructor for Arduino SPI bus object of the toolkit - - @param rhs source of the copy operation - */ - sfeTkArdSPI(sfeTkArdSPI const &rhs) : sfeTkISPI(), _spiPort{rhs._spiPort}, _sfeSPISettings{rhs._sfeSPISettings} - { - } - - /** - @brief Assignment copy operator for Arduino SPI bus object of the toolkit - - @param rhs The right hand side of the assignment. - @return sfeTkArdSPI& - The left hand side of the assignment. - */ - sfeTkArdSPI &operator=(const sfeTkArdSPI &rhs) - { - _spiPort = rhs._spiPort; - _sfeSPISettings = rhs._sfeSPISettings; - return *this; - } - - /** - @brief Method sets up the required SPI settings. - @note This function provides a default SPI Port. - - @param bInit Init the device - default is false. - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t init(bool bInit = false); - - /** - @brief Method sets up the required SPI settings. - @note This function provides a default SPI Port. - - @param csPin The CS Pin for the device - @param bInit Init the device - default is false. - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t init(uint8_t csPin, bool bInit = false); - - /** - @brief Method sets up the required SPI settings. - - @param spiPort Port for SPI communication. - @param busSPISettings Settings for speed, endianness, and spi mode of the SPI bus. - @param csPin The CS Pin for the device - @param bInit This flag tracks whether the bus has been initialized. - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t init(SPIClass &spiPort, SPISettings &busSPISettings, uint8_t csPin, bool bInit = false); - - /** - @brief Write a single byte to the device - - @param data Data to write. - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t writeByte(uint8_t data); - - /** - @brief Write a single byte to the given register - - @param devReg The device's register's address. - @param data Data to write. - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t writeRegisterByte(uint8_t devReg, uint8_t data); - - /** - @brief Write a single word to the given register - - @param devReg The device's register's address. - @param data Data to write. - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t writeRegisterWord(uint8_t devReg, uint16_t data); - - /** - @brief Writes a number of bytes starting at the given register's address. - @note This method is virtual to allow it to be overridden to support a device that requires a unique impl - - @param devReg The device's register's address. - @param data Data to write. - @param length - length of data - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t writeRegisterRegion(uint8_t devReg, const uint8_t *data, size_t length); - - /** - @brief Writes a number of bytes starting at the given register's address. - @note This method is virtual to allow it to be overridden to support a device that requires a unique impl - - @param devReg The device's register's address. - @param data Data to write. - @param length - length of data - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t writeRegister16Region(uint16_t devReg, const uint8_t *data, size_t length); - - /** - @brief Read a single byte from the given register - - @param devReg The device's register's address. - @param[out] data Data to read. - - @retval sfeTkError_t - kSTkErrOk on success - */ - sfeTkError_t readRegisterByte(uint8_t devReg, uint8_t &data); - - /** - @brief read a single word to the given register - - @param devReg The device's register's address. - @param[out] data Data to write. - - @retval sfeTkError_t - true on success - */ - sfeTkError_t readRegisterWord(uint8_t devReg, uint16_t &data); - - /** - @brief Reads a block of data from the given register. - @note This method is virtual to allow it to be overridden to support a device that requires a unique impl - - @param reg The device's register's address. - @param[out] data Data buffer to read into - @param numBytes - length of data/size of data buffer - @param[out] readBytes - Number of bytes read - - @retval sfeTkError_t - true on success - */ - virtual sfeTkError_t readRegisterRegion(uint8_t reg, uint8_t *data, size_t numBytes, size_t &readBytes); - - /** - @brief Reads a block of data from the given register. - @note This method is virtual to allow it to be overridden to support a device that requires a unique impl - - @param reg The device's register's 16 bit address. - @param[out] data Data buffer to read into - @param numBytes - Length of data to read/size of data buffer - @param[out] readBytes - Number of bytes read - - @retval sfeTkError_t - true on success - */ - virtual sfeTkError_t readRegister16Region(uint16_t reg, uint8_t *data, size_t numBytes, size_t &readBytes); - - protected: - // note: The instance data is protected, allowing access if a sub-class is - // created to implement a special read/write routine - // - /** Pointer to the spi port being used */ - SPIClass *_spiPort; - - /** This objects spi settings are used for every transaction. */ - SPISettings _sfeSPISettings; -}; From 3663b74e5830b906a9ac7e14ccb702cbbec1fecb Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 15:21:46 -0600 Subject: [PATCH 11/34] Fixes submodule path (maybe) --- .gitmodules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 922dfb6..0acaf5b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "src/bus"] - path = src/bus - url = https://github.com/sparkfun/SparkFun_Toolkit.git +[submodule "SparkFun_Toolkit/src"] + path = src/ + url = https://github.com/sparkfun/SparkFun_Toolkit.git From 00e5dd62c51a13b90cb6fcf4721ca49b409335f5 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 15:24:31 -0600 Subject: [PATCH 12/34] Adds toolkit as dependency for Arduino library manager --- library.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library.properties b/library.properties index bf9d5be..7379c70 100644 --- a/library.properties +++ b/library.properties @@ -6,4 +6,5 @@ sentence=A library to use the SparkFun Qwiic Ultrasonic Distance Sensor paragraph= category=Sensors url=https://github.com/sparkfun/SparkFun_Qwiic_Ultrasonic_Arduino_Library -architectures=* \ No newline at end of file +architectures=* +depends=SparkFun_Toolkit From 452306380c879696549ce8d5c8613eb7808f4ce5 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 15:27:53 -0600 Subject: [PATCH 13/34] Removes underscore in Toolkit listing --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 7379c70..2af7d39 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph= category=Sensors url=https://github.com/sparkfun/SparkFun_Qwiic_Ultrasonic_Arduino_Library architectures=* -depends=SparkFun_Toolkit +depends=SparkFun Toolkit From 69973291f0cad49bececebf504b685b4898ae66d Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 15:37:33 -0600 Subject: [PATCH 14/34] Removes git submodule --- .gitmodules | 3 --- src/sfeQwiicUltrasonic.cpp | 1 - 2 files changed, 4 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 0acaf5b..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "SparkFun_Toolkit/src"] - path = src/ - url = https://github.com/sparkfun/SparkFun_Toolkit.git diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index aad03c7..9b43417 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -10,7 +10,6 @@ */ #include "sfeQwiicUltrasonic.h" -#include sfeTkError_t sfeQwiicUltrasonic::begin(sfeTkII2C *theBus) { From e5bf0b22bc99516748575d128f16490314cbc6e3 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 30 May 2024 15:47:11 -0600 Subject: [PATCH 15/34] Updates workflow --- .github/workflows/compile-sketch.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/compile-sketch.yml b/.github/workflows/compile-sketch.yml index bcc922a..ec7edf6 100644 --- a/.github/workflows/compile-sketch.yml +++ b/.github/workflows/compile-sketch.yml @@ -98,6 +98,7 @@ jobs: fqbn: ${{ matrix.board.fqbn }} libraries: | - source-path: ./ + - name: SparkFun Toolkit sketch-paths: | - examples/Example1_BasicReadings enable-warnings-report: true From 0b4ba7ac54d6fc64e7d1df07134d259a1748d3d8 Mon Sep 17 00:00:00 2001 From: santised Date: Fri, 31 May 2024 08:51:01 -0600 Subject: [PATCH 16/34] Fixes polarity of echo pin to reflect change to firmware --- .../Example2_BasicDistanceTrigger.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino b/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino index 0c989ae..8c387db 100644 --- a/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino +++ b/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino @@ -60,7 +60,7 @@ void loop() { distanceRequested = 1; } - if (digitalRead(echoPin) == LOW) { + if (digitalRead(echoPin) == HIGH) { uint16_t distance = 0; myUltrasonic.getTriggeredDistance(distance); From 787e4105bb9cb979ea9167785bd8d87697288ffc Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Mon, 3 Jun 2024 10:03:05 -0600 Subject: [PATCH 17/34] Cleaning up last example --- .../Example3_ChangeAddress.ino | 28 ++++++++----------- library.properties | 1 - src/sfeQwiicUltrasonic.cpp | 1 + 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino index 8217410..f3186a9 100644 --- a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino +++ b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino @@ -37,41 +37,35 @@ void setup() Wire.begin(); + // This sketch wont' run until you open the serial monitor while(!Serial) ; // Attempt to begin the sensor - if (myUltrasonic.begin(deviceAddress) == false) + if (myUltrasonic.begin(kQwiicUltrasonicDefaultAddress) == false ) { Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); - while(1) - ; } Serial.println("Ready to change address."); delay(1000); -} - -void loop() -{ Serial.print("Changing Address To: "); Serial.println(NEW_ADDR, HEX); + // Call change address..... myUltrasonic.changeAddress(NEW_ADDR); delay(1000); - Serial.println("Attempting to communicate with new address..."); - if (myUltrasonic.begin(NEW_ADDR) == false) - { - Serial.println("Ultrasonic sensor address did not change, ensure you picked a viable address."); - while(1) - ; - } - - Serial.println("Address changed successfully: "); - Serial.println(NEW_ADDR, HEX); + Serial.print("Load up example 1 with the new address at: "); + Serial.println(NEW_ADDR, HEX); + Serial.println("Freezing...."); while(1) ; + +} + +void loop() +{ } diff --git a/library.properties b/library.properties index 2af7d39..02bbaa5 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,3 @@ paragraph= category=Sensors url=https://github.com/sparkfun/SparkFun_Qwiic_Ultrasonic_Arduino_Library architectures=* -depends=SparkFun Toolkit diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 9b43417..924528e 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -84,6 +84,7 @@ sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) // Check whether the address is valid sfeTkError_t err; size_t numBytes = 2; + // We want to shift the address left before we send it. address <<= 1; const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, address}; From b47b59589e7ec6000724cbd7decc8a1828e0a927 Mon Sep 17 00:00:00 2001 From: santised Date: Tue, 4 Jun 2024 19:19:35 -0600 Subject: [PATCH 18/34] Re-adds dependency * Accidentally blasts it in the last commit --- library.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/library.properties b/library.properties index 02bbaa5..2af7d39 100644 --- a/library.properties +++ b/library.properties @@ -7,3 +7,4 @@ paragraph= category=Sensors url=https://github.com/sparkfun/SparkFun_Qwiic_Ultrasonic_Arduino_Library architectures=* +depends=SparkFun Toolkit From 9e4e186a8a5da099024bf76c2aeb71132704d46b Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 6 Jun 2024 16:02:09 -0600 Subject: [PATCH 19/34] Re-adds original `changeAddress` function and changes the current on in this branch to: `updateAddress` * Re-adds original address list * Adds constants for general min and max i2c addresses * Updates language around the address related functions --- .../Example1_BasicReadings.ino | 5 +-- .../Example2_BasicDistanceTrigger.ino | 5 +-- .../Example3_ChangeAddress.ino | 3 +- src/sfeQwiicUltrasonic.cpp | 37 ++++++++++--------- src/sfeQwiicUltrasonic.h | 23 ++++++++---- 5 files changed, 42 insertions(+), 31 deletions(-) diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index c5bb5a3..0061dd3 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -33,11 +33,10 @@ void setup() Wire.begin(); // Attempt to begin the sensor - if (myUltrasonic.begin(deviceAddress) == false) + while (myUltrasonic.begin(deviceAddress) == false) { Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); - while(1) - ; + delay(2000); } Serial.println("Ultrasonic sensor connected!"); diff --git a/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino b/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino index 8c387db..46461ed 100644 --- a/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino +++ b/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino @@ -38,11 +38,10 @@ void setup() { pinMode(echoPin, INPUT); // Attempt to begin the sensor - if (myUltrasonic.begin(deviceAddress) == false) + while (myUltrasonic.begin(deviceAddress) == false) { Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); - while(1) - ; + delay(2000); } Serial.println("Ultrasonic sensor connected!"); diff --git a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino index f3186a9..202f8ba 100644 --- a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino +++ b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino @@ -42,9 +42,10 @@ void setup() ; // Attempt to begin the sensor - if (myUltrasonic.begin(kQwiicUltrasonicDefaultAddress) == false ) + while (myUltrasonic.begin(deviceAddress) == false) { Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); + delay(2000); } Serial.println("Ready to change address."); diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 924528e..2608dfa 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -10,6 +10,8 @@ */ #include "sfeQwiicUltrasonic.h" +#include "sfeTk/sfeTkError.h" +#include sfeTkError_t sfeQwiicUltrasonic::begin(sfeTkII2C *theBus) { @@ -42,12 +44,12 @@ sfeTkError_t sfeQwiicUltrasonic::isConnected() sfeTkError_t sfeQwiicUltrasonic::getDistance(uint16_t &distance) { - size_t bytesRead = 0; - uint8_t rawData[2] = {0, 0}; - sfeTkError_t err; + size_t bytesRead; + size_t numBytes = 2; + uint8_t rawData[2] = {}; - _theBus->writeByte(kUltrasonicDistanceReadCommand); - err = _theBus->readRegisterRegion(_theBus->address(), rawData, 2, bytesRead); + // Get the distance + sfeTkError_t err = _theBus->readBlock(kUltrasonicDistanceReadCommand, rawData, numBytes, bytesRead); // Check whether the read was successful if (err != kSTkErrOk) @@ -60,39 +62,40 @@ sfeTkError_t sfeQwiicUltrasonic::getDistance(uint16_t &distance) return kSTkErrOk; } -sfeTkError_t sfeQwiicUltrasonic::getTriggeredDistance(uint16_t &distance) +sfeTkError_t sfeQwiicUltrasonic::changeAddress(const uint8_t &address) { - size_t bytesRead = 0; - uint8_t rawData[2] = {0, 0}; + // Check whether the address is valid + if (address < kQwiicUltrasonicMinAddress || address > kQwiicUltrasonicMaxAddress) + return kSTkErrFail; - // Attempt to read the distance - sfeTkError_t err = _theBus->readRegisterRegion(_theBus->address(), rawData, 2, bytesRead); + // Write the new address to the device. The first bit must be set to 1 + sfeTkError_t err = _theBus->writeByte(address | 0x80); - // Check whether the read was successful + // Check whether the write was successful if (err != kSTkErrOk) return err; - // Store raw data - distance = (rawData[0] << 8) | rawData[1]; + // Update the address in the bus + _theBus->setAddress(address); // Done! return kSTkErrOk; } -sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) +sfeTkError_t sfeQwiicUltrasonic::updateAddress(uint8_t &address) { // Check whether the address is valid sfeTkError_t err; size_t numBytes = 2; // We want to shift the address left before we send it. + address <<= 1; const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, address}; - if (address < kQwiicUltrasonicMinAddress || address > kQwiicUltrasonicMaxAddress) + if (address < kQwiicI2CAddressMin|| address > kQwiicI2CAddressMax) return kSTkErrFail; - // Write the new address to the device. The first bit must be set to 1 - // err = _theBus->writeRegisterByte(kUltrasonicAddressChangeCommand, (address<< 1)); + // Write the new address to the device. err = _theBus->writeBlock(toWrite, numBytes); // Check whether the write was successful diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index 8270f1a..34f3356 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -16,8 +16,17 @@ // Available I2C addresses of the Qwiic Ultrasonic const uint8_t kQwiicUltrasonicDefaultAddress = 0x2F; -const uint8_t kQwiicUltrasonicMinAddress = 0x08; -const uint8_t kQwiicUltrasonicMaxAddress = 0x7F; +// These addresses are the min and max (respectively) of valid I2C addresses that can +// be used for the newest revision of the Qwiic Ultrasonic sensor. +const uint8_t kQwiicI2CAddressMin = 0x08; +const uint8_t kQwiicI2CAddressMax = 0x7F; +// Available I2C addresses of the Qwiic Ultrasonic +const uint8_t kQwiicUltrasonicDefaultAddress = 0x2F; +const uint8_t kQwiicUltrasonicAddresses[] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F}; +const uint8_t kQwiicUltrasonicNumAddresses = sizeof(kQwiicUltrasonicAddresses) / sizeof(uint8_t); +const uint8_t kQwiicUltrasonicMinAddress = kQwiicUltrasonicAddresses[0]; +const uint8_t kQwiicUltrasonicMaxAddress = kQwiicUltrasonicAddresses[15];; // I2C commands const uint8_t kUltrasonicDistanceReadCommand = 0x01; const uint8_t kUltrasonicAddressChangeCommand = 0x04; @@ -44,15 +53,15 @@ class sfeQwiicUltrasonic /// @return 0 for succuss, negative for errors, positive for warnings sfeTkError_t getDistance(uint16_t &distance); - /// @brief Triggers a new measurement and reads the previous one - /// @param distance Distance in mm + /// @brief Changes the I2C address of older Qwiic Ultrasonic sensors. + /// @param address New address, must be in the range 0x20 to 0x2F /// @return 0 for succuss, negative for errors, positive for warnings - sfeTkError_t getTriggeredDistance(uint16_t &distance); + sfeTkError_t changeAddress(const uint8_t &address); - /// @brief Changes the I2C address of the Qwiic Ultrasonic sensor + /// @brief Changes the I2C address of the latest revision of the Qwiic Ultrasonic sensor. /// @param address New address, must be in the range 0x20 to 0x2F /// @return 0 for succuss, negative for errors, positive for warnings - sfeTkError_t changeAddress(uint8_t &address); + sfeTkError_t updateAddress(uint8_t &address); /// @brief Gets the current I2C address being used by the library for the Qwiic Ultrasonic sensor /// @return The current I2C address, 7-bit unshifted From c6415b9e381033978d10872852e54abc5a30fd23 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 6 Jun 2024 20:41:59 -0600 Subject: [PATCH 20/34] Changes conversion function * Changes initiation check * Removes extraneous const --- .../Example4_OLED_Distance.ino | 13 ++++++------- src/sfeQwiicUltrasonic.h | 1 - 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino b/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino index ae3c81f..575da78 100644 --- a/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino +++ b/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino @@ -48,17 +48,16 @@ void setup() Serial.println("Ultrasonic Distance Sensor - Example 4 - Distance on an OLED Display"); Wire.begin(); - if (myOLED.begin() == false) { + while (myOLED.begin() == false) { Serial.println("OLED sensor not connected, check your wiring and I2C address!"); - while (1) - ; + delay(1000); } - if (myUltrasonic.begin(deviceAddress) == false) + while(myUltrasonic.begin(deviceAddress) == false) { Serial.println("Ultrasonic sensor not connected, check your wiring and I2C address!"); - while(1) - ; + delay(1000); } + String hello = "Hello, Ultrasonic!"; // This is good for the narrow OLED screen. You can also just remove this @@ -82,7 +81,7 @@ void loop() myUltrasonic.getDistance(distance); // Convert distance, which is an integer, to char so that we can print it. - itoa(distance, distanceBuff, 10); + snprintf(distanceBuff, 4, "%d", distance); // Put the distance in a string so that we can also print "mm". distanceStr = distanceBuff; diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index 34f3356..71e95cb 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -21,7 +21,6 @@ const uint8_t kQwiicUltrasonicDefaultAddress = 0x2F; const uint8_t kQwiicI2CAddressMin = 0x08; const uint8_t kQwiicI2CAddressMax = 0x7F; // Available I2C addresses of the Qwiic Ultrasonic -const uint8_t kQwiicUltrasonicDefaultAddress = 0x2F; const uint8_t kQwiicUltrasonicAddresses[] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F}; const uint8_t kQwiicUltrasonicNumAddresses = sizeof(kQwiicUltrasonicAddresses) / sizeof(uint8_t); From d5ecebc13b2baee0f071901c29c7068239a8d717 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 6 Jun 2024 20:50:41 -0600 Subject: [PATCH 21/34] Adds link to OLED library --- examples/Example4_OLED_Distance/Example4_OLED_Distance.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino b/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino index 575da78..39a8eba 100644 --- a/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino +++ b/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino @@ -5,6 +5,8 @@ * * https://www.sparkfun.com/1XXXX * * SparkFun Qwiic Narrow OLED Display (LCD-1XXXX) * * https://www.sparkfun.com/1XXXX + * + * Link to OLED library: https://github.com/sparkfun/SparkFun_Qwiic_OLED_Arduino_Library * * Written By: Elias Santistevan * Date: 06/2024 From 41d07b8acdc64e021a5b466238c6ed1d1365d23c Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 6 Jun 2024 20:57:11 -0600 Subject: [PATCH 22/34] Adds updated method for changing address while commenting out older method --- .../Example3_ChangeAddress.ino | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino index 202f8ba..a0ab3d2 100644 --- a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino +++ b/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino @@ -28,6 +28,9 @@ uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F // New addres is 7-bit unshifted. uint8_t NEW_ADDR = 0x1E; +//If using an older version of the Qwiic Ultrasonic, your address range is: 0x20 - 0x2F +//uint8_t NEW_ADDR = 0x2F; + void setup() { @@ -54,9 +57,24 @@ void setup() Serial.print("Changing Address To: "); Serial.println(NEW_ADDR, HEX); + // Call change address..... - myUltrasonic.changeAddress(NEW_ADDR); + sfeTkError_t err = myUltrasonic.updateAddress(NEW_ADDR); + // If you have an older version of the Qwiic Ultrasonic, you'll need to use the following: + //sfeTkError_t err = myUltrasonic.changeAddress(NEW_ADDR); + + if(err) + { + while(1) + { + Serial.print("Error changing address: "); + Serial.println(err); + delay(1000); + } + } delay(1000); + + // I Serial.print("Load up example 1 with the new address at: "); From b8715e0d8ccf56a0b27e053059ef95d3b7bf54d4 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 6 Jun 2024 21:00:32 -0600 Subject: [PATCH 23/34] Reorders examples --- .../Example2_OLED_Distance.ino} | 0 .../Example3_Trigger_Echo.ino} | 0 .../Example4_ChangeAddress.ino} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename examples/{Example4_OLED_Distance/Example4_OLED_Distance.ino => Example2_OLED_Distance/Example2_OLED_Distance.ino} (100%) rename examples/{Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino => Example3_Trigger_Echo/Example3_Trigger_Echo.ino} (100%) rename examples/{Example3_ChangeAddress/Example3_ChangeAddress.ino => Example4_ChangeAddress/Example4_ChangeAddress.ino} (100%) diff --git a/examples/Example4_OLED_Distance/Example4_OLED_Distance.ino b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino similarity index 100% rename from examples/Example4_OLED_Distance/Example4_OLED_Distance.ino rename to examples/Example2_OLED_Distance/Example2_OLED_Distance.ino diff --git a/examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino b/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino similarity index 100% rename from examples/Example2_BasicDistanceTrigger/Example2_BasicDistanceTrigger.ino rename to examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino diff --git a/examples/Example3_ChangeAddress/Example3_ChangeAddress.ino b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino similarity index 100% rename from examples/Example3_ChangeAddress/Example3_ChangeAddress.ino rename to examples/Example4_ChangeAddress/Example4_ChangeAddress.ino From c4f3779f83975e925c2a5f2294e4b94f4f1e9800 Mon Sep 17 00:00:00 2001 From: santised Date: Thu, 6 Jun 2024 21:13:00 -0600 Subject: [PATCH 24/34] Adds example using trigger and echo pins --- .../Example2_OLED_Distance.ino | 2 +- .../Example3_Trigger_Echo.ino | 48 +++++++++---------- .../Example4_ChangeAddress.ino | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino index 39a8eba..14ff2e3 100644 --- a/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino +++ b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino @@ -1,4 +1,4 @@ -/* SparkFun Ulrasonic Distance Sensor - Example 4 Basic Distance Sensing on an OLED Display +/* SparkFun Ulrasonic Distance Sensor - Example 2 Basic Distance Sensing on an OLED Display * * Products: * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) diff --git a/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino b/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino index 46461ed..2d994ff 100644 --- a/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino +++ b/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino @@ -1,4 +1,4 @@ -/* SparkFun Ulrasonic Distance Sensor - Example 2 Basic Distance Sensing using Trigger and Echo Pins. +/* SparkFun Ulrasonic Distance Sensor - Example 3 - Distance using Trigger and Echo Pins * * Product: * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) @@ -23,9 +23,15 @@ QwiicUltrasonic myUltrasonic; uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F // uint8_t deviceAddress = 0x00; +// Adjust these to your setup. const int triggerPin = 7; // Trigger Pin of Ultrasonic Sensor const int echoPin = 8; // Echo Pin of Ultrasonic Sensor -int distanceRequested = 0; + +// Used for distance calculation +float distance = 0.0; +float duration = 0.0; +const float speedOfSound = 340.00; // Speed of sound in m/s +const float convMilli= 1000.00; // Speed of sound in m/s void setup() { @@ -49,32 +55,26 @@ void setup() { void loop() { - if(distanceRequested == 0) - { - // To trigger we write the pin high and then back to its resting state. - digitalWrite(triggerPin, HIGH); - delay(5); - digitalWrite(triggerPin, LOW); - // We don't want continually trigger while data is being retrieved from the sensor. - distanceRequested = 1; - } - - if (digitalRead(echoPin) == HIGH) { + digitalWrite(triggerPin, HIGH); + delay(5); + digitalWrite(triggerPin, LOW); + // We don't want continually trigger while data is being retrieved from the sensor. - uint16_t distance = 0; - myUltrasonic.getTriggeredDistance(distance); + duration = pulseIn(echoPin, HIGH); + // Time until sound detected * speed of sound * conversion to mm + // Divide by two because we only want the time the wave traveled to the object, + // not to the object and back. + distance = (duration * speedOfSound * convMilli) / 2; - // Print measurement - Serial.print("Distance (mm): "); - Serial.println(distance); + // Print measurement + Serial.print("Distance (mm): "); + Serial.println(distance); - //Serial.println("Distance (cm): "); - //Serial.print((distance / 10.0), 2); + //Serial.println("Distance (cm): "); + //Serial.print((distance / 10.0), 2); - //Serial.println("Distace (in): "); - //Serial.print((distance / 25.4), 2); + //Serial.println("Distace (in): "); + //Serial.print((distance / 25.4), 2); - distanceRequested = 0; - } delay(500); } diff --git a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino index a0ab3d2..94fa5f1 100644 --- a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino +++ b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino @@ -1,4 +1,4 @@ -/* SparkFun Ulrasonic Distance Sensor - Example 3 Changing the Ultrasonic's Address +/* SparkFun Ulrasonic Distance Sensor - Example 4 Changing the Ultrasonic's Address * To reset the original I2C address, ground the "RST" pad on the backside of the board. * by touching a wire to the pad and then to ground. The address will be reset to 0x2F. * From ac1f21774029312a34dce9f36467c2f42c0d9f87 Mon Sep 17 00:00:00 2001 From: santised Date: Fri, 14 Jun 2024 08:36:13 -0600 Subject: [PATCH 25/34] Removes include --- src/sfeQwiicUltrasonic.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 2608dfa..90e5931 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -11,7 +11,6 @@ #include "sfeQwiicUltrasonic.h" #include "sfeTk/sfeTkError.h" -#include sfeTkError_t sfeQwiicUltrasonic::begin(sfeTkII2C *theBus) { From 35223a50c70cda02240dcca4cbc94ccd96aa73ac Mon Sep 17 00:00:00 2001 From: santised Date: Tue, 18 Jun 2024 07:21:42 -0600 Subject: [PATCH 26/34] Adds new parameter to constructor, updates examples with new parameter * With new parameter, `updateAddress` was no longer needed --- .../Example1_BasicReadings.ino | 2 +- .../Example2_OLED_Distance.ino | 5 +- .../Example3_Trigger_Echo.ino | 4 +- .../Example4_ChangeAddress.ino | 17 ++--- library.properties | 1 - src/sfeQwiicUltrasonic.cpp | 75 ++++++++++--------- src/sfeQwiicUltrasonic.h | 43 ++++++----- 7 files changed, 73 insertions(+), 74 deletions(-) diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index 0061dd3..deabfcc 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -15,7 +15,7 @@ #include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" // Create an ultrasonic sensor object -QwiicUltrasonic myUltrasonic; +QwiicUltrasonic myUltrasonic(kQwiicUltrasonicFWLatest); // Here we set the device address. Note that an older version of the Qwiic // Ultrasonic firmware used a default address of 0x00. If yours uses 0x00, diff --git a/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino index 14ff2e3..a5500b1 100644 --- a/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino +++ b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino @@ -23,11 +23,8 @@ #include "res/qw_fnt_8x16.h" #include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" -const int TRIG_PIN = 7; -const int ECHO_PIN = 8; - // Create an ultrasonic sensor object -QwiicUltrasonic myUltrasonic; +QwiicUltrasonic myUltrasonic(kQwiicUltrasonicFWLatest); // Creat an OLED object QwiicNarrowOLED myOLED; diff --git a/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino b/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino index 2d994ff..c21f829 100644 --- a/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino +++ b/examples/Example3_Trigger_Echo/Example3_Trigger_Echo.ino @@ -31,7 +31,7 @@ const int echoPin = 8; // Echo Pin of Ultrasonic Sensor float distance = 0.0; float duration = 0.0; const float speedOfSound = 340.00; // Speed of sound in m/s -const float convMilli= 1000.00; // Speed of sound in m/s +const float millisPerSecond= 1000.00; // Number of milliseconds in a second void setup() { @@ -64,7 +64,7 @@ void loop() { // Time until sound detected * speed of sound * conversion to mm // Divide by two because we only want the time the wave traveled to the object, // not to the object and back. - distance = (duration * speedOfSound * convMilli) / 2; + distance = (duration * speedOfSound * millisPerSecond) / 2; // Print measurement Serial.print("Distance (mm): "); diff --git a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino index 94fa5f1..fb17fb7 100644 --- a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino +++ b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino @@ -17,7 +17,7 @@ #include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" // Create an ultrasonic sensor object -QwiicUltrasonic myUltrasonic; +QwiicUltrasonic myUltrasonic(kQwiicUltrasonicFWLatest); // Here we set the device address. Note that an older version of the Qwiic // Ultrasonic firmware used a default address of 0x00. If yours uses 0x00, @@ -27,9 +27,9 @@ uint8_t deviceAddress = kQwiicUltrasonicDefaultAddress; // 0x2F // uint8_t deviceAddress = 0x00; // New addres is 7-bit unshifted. -uint8_t NEW_ADDR = 0x1E; +uint8_t newAddr = 0x20; //If using an older version of the Qwiic Ultrasonic, your address range is: 0x20 - 0x2F -//uint8_t NEW_ADDR = 0x2F; +//uint8_t newAddr = 0x2F; void setup() @@ -55,13 +55,11 @@ void setup() delay(1000); Serial.print("Changing Address To: "); - Serial.println(NEW_ADDR, HEX); + Serial.println(newAddr, HEX); // Call change address..... - sfeTkError_t err = myUltrasonic.updateAddress(NEW_ADDR); - // If you have an older version of the Qwiic Ultrasonic, you'll need to use the following: - //sfeTkError_t err = myUltrasonic.changeAddress(NEW_ADDR); + sfeTkError_t err = myUltrasonic.changeAddress(newAddr); if(err) { @@ -74,11 +72,8 @@ void setup() } delay(1000); - // I - - Serial.print("Load up example 1 with the new address at: "); - Serial.println(NEW_ADDR, HEX); + Serial.println(newAddr, HEX); Serial.println("Freezing...."); while(1) ; diff --git a/library.properties b/library.properties index 2af7d39..02bbaa5 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,3 @@ paragraph= category=Sensors url=https://github.com/sparkfun/SparkFun_Qwiic_Ultrasonic_Arduino_Library architectures=* -depends=SparkFun Toolkit diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 90e5931..a7f9612 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -19,15 +19,18 @@ sfeTkError_t sfeQwiicUltrasonic::begin(sfeTkII2C *theBus) return kSTkErrFail; // Check the device address - if (theBus->address() < kQwiicUltrasonicMinAddress || theBus->address() > kQwiicUltrasonicMaxAddress) + if(_fwVersion == kQwiicUltrasonicFWOld) { - // An older version of the firmware used 0x00 as the default address. - // It's not really a valid address, but we need to allow it. Any other - // address can't be used - if (theBus->address() != 0x00) - return kSTkErrFail; - } + if (theBus->address() < kQwiicUltrasonicMinAddress || theBus->address() > kQwiicUltrasonicMaxAddress) + { + // An older version of the firmware used 0x00 as the default address. + // It's not really a valid address, but we need to allow it. Any other + // address can't be used + if (theBus->address() != 0x00) + return kSTkErrFail; + } + } // Set bus pointer _theBus = theBus; @@ -48,7 +51,8 @@ sfeTkError_t sfeQwiicUltrasonic::getDistance(uint16_t &distance) uint8_t rawData[2] = {}; // Get the distance - sfeTkError_t err = _theBus->readBlock(kUltrasonicDistanceReadCommand, rawData, numBytes, bytesRead); + //sfeTkError_t err = _theBus->readBlock(kUltrasonicDistanceReadCommand, rawData, numBytes, bytesRead); + sfeTkError_t err = _theBus->readRegisterRegion(kUltrasonicDistanceReadCommand, rawData, numBytes, bytesRead); // Check whether the read was successful if (err != kSTkErrOk) @@ -61,41 +65,40 @@ sfeTkError_t sfeQwiicUltrasonic::getDistance(uint16_t &distance) return kSTkErrOk; } -sfeTkError_t sfeQwiicUltrasonic::changeAddress(const uint8_t &address) +sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) { // Check whether the address is valid - if (address < kQwiicUltrasonicMinAddress || address > kQwiicUltrasonicMaxAddress) - return kSTkErrFail; - - // Write the new address to the device. The first bit must be set to 1 - sfeTkError_t err = _theBus->writeByte(address | 0x80); - - // Check whether the write was successful - if (err != kSTkErrOk) - return err; - // Update the address in the bus - _theBus->setAddress(address); + sfeTkError_t err; - // Done! - return kSTkErrOk; -} + if(_fwVersion == kQwiicUltrasonicFWOld) + { + // Old firmware only supports a limited range of addresses. + if (address < kQwiicUltrasonicMinAddress || address > kQwiicUltrasonicMaxAddress) + return kSTkErrFail; -sfeTkError_t sfeQwiicUltrasonic::updateAddress(uint8_t &address) -{ - // Check whether the address is valid - sfeTkError_t err; - size_t numBytes = 2; - // We want to shift the address left before we send it. - - address <<= 1; - const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, address}; + // Write the new address to the device. The first bit must be set to 1 + err = _theBus->writeByte(address | 0x80); + } + else if(_fwVersion == kQwiicUltrasonicFWLatest) + { + size_t numBytes = 2; + // Latest firmware versions supports all of the available I2C addresses. + if (address < kQwiicUltrasonicI2CAddressMin || address > kQwiicUltrasonicI2CAddressMax) + return kSTkErrFail; - if (address < kQwiicI2CAddressMin|| address > kQwiicI2CAddressMax) - return kSTkErrFail; + // We want to shift the address left before we send it. + address <<= 1; + const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, address}; - // Write the new address to the device. - err = _theBus->writeBlock(toWrite, numBytes); + //Write the new address to the device + err = _theBus->writeBlock(toWrite, numBytes); + } + else { + //There was some error setting the version in the constructor + //return an error. + return kSTkErrOk; + } // Check whether the write was successful if (err != kSTkErrOk) diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index 71e95cb..3b06d0e 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -1,9 +1,9 @@ -/* SparkFun Ulrasonic Distance Sensor - * - * Product: +/* SparkFun Ulrasonic Distance Sensor + * + * Product: * * SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 (SEN-1XXXX) * * https://www.sparkfun.com/1XXXX - * + * * SPDX-License-Identifier: MIT * * Copyright (c) 2024 SparkFun Electronics @@ -12,20 +12,21 @@ #pragma once #include "SparkFun_Toolkit.h" -#include // Available I2C addresses of the Qwiic Ultrasonic const uint8_t kQwiicUltrasonicDefaultAddress = 0x2F; + +const uint8_t kQwiicUltrasonicFWLatest = 0x01; +const uint8_t kQwiicUltrasonicFWOld = 0x10; + // These addresses are the min and max (respectively) of valid I2C addresses that can // be used for the newest revision of the Qwiic Ultrasonic sensor. -const uint8_t kQwiicI2CAddressMin = 0x08; -const uint8_t kQwiicI2CAddressMax = 0x7F; +const uint8_t kQwiicUltrasonicI2CAddressMin = 0x08; +const uint8_t kQwiicUltrasonicI2CAddressMax = 0x7F; // Available I2C addresses of the Qwiic Ultrasonic -const uint8_t kQwiicUltrasonicAddresses[] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F}; -const uint8_t kQwiicUltrasonicNumAddresses = sizeof(kQwiicUltrasonicAddresses) / sizeof(uint8_t); -const uint8_t kQwiicUltrasonicMinAddress = kQwiicUltrasonicAddresses[0]; -const uint8_t kQwiicUltrasonicMaxAddress = kQwiicUltrasonicAddresses[15];; +const uint8_t kQwiicUltrasonicMinAddress = 0x20; +const uint8_t kQwiicUltrasonicMaxAddress = 0x2F; +; // I2C commands const uint8_t kUltrasonicDistanceReadCommand = 0x01; const uint8_t kUltrasonicAddressChangeCommand = 0x04; @@ -34,10 +35,16 @@ class sfeQwiicUltrasonic { public: /// @brief Default constructor - sfeQwiicUltrasonic() : _theBus(nullptr) + sfeQwiicUltrasonic() : _theBus(nullptr), _fwVersion(kQwiicUltrasonicFWLatest) { } + /// @brief Default constructor + sfeQwiicUltrasonic(uint8_t fwVersion) : _theBus(nullptr), _fwVersion(fwVersion) + { + } + + /// @brief Begins the Qwiic Ultrasonic sensor /// @param theBus I2C bus to use for communication /// @return 0 for succuss, negative for errors, positive for warnings @@ -55,12 +62,7 @@ class sfeQwiicUltrasonic /// @brief Changes the I2C address of older Qwiic Ultrasonic sensors. /// @param address New address, must be in the range 0x20 to 0x2F /// @return 0 for succuss, negative for errors, positive for warnings - sfeTkError_t changeAddress(const uint8_t &address); - - /// @brief Changes the I2C address of the latest revision of the Qwiic Ultrasonic sensor. - /// @param address New address, must be in the range 0x20 to 0x2F - /// @return 0 for succuss, negative for errors, positive for warnings - sfeTkError_t updateAddress(uint8_t &address); + sfeTkError_t changeAddress(uint8_t &address); /// @brief Gets the current I2C address being used by the library for the Qwiic Ultrasonic sensor /// @return The current I2C address, 7-bit unshifted @@ -68,4 +70,7 @@ class sfeQwiicUltrasonic protected: sfeTkII2C *_theBus; + + private: + uint8_t _fwVersion = 0x00; }; From fe2c0aa319056233b12364218b40d07dfe4d033a Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Tue, 18 Jun 2024 12:49:10 -0600 Subject: [PATCH 27/34] Minor fix to function calls now used in the toolkit --- examples/Example1_BasicReadings/Example1_BasicReadings.ino | 2 +- library.properties | 1 + src/sfeQwiicUltrasonic.cpp | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index deabfcc..0061dd3 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -15,7 +15,7 @@ #include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" // Create an ultrasonic sensor object -QwiicUltrasonic myUltrasonic(kQwiicUltrasonicFWLatest); +QwiicUltrasonic myUltrasonic; // Here we set the device address. Note that an older version of the Qwiic // Ultrasonic firmware used a default address of 0x00. If yours uses 0x00, diff --git a/library.properties b/library.properties index 02bbaa5..2af7d39 100644 --- a/library.properties +++ b/library.properties @@ -7,3 +7,4 @@ paragraph= category=Sensors url=https://github.com/sparkfun/SparkFun_Qwiic_Ultrasonic_Arduino_Library architectures=* +depends=SparkFun Toolkit diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index a7f9612..40c2fc1 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -51,7 +51,6 @@ sfeTkError_t sfeQwiicUltrasonic::getDistance(uint16_t &distance) uint8_t rawData[2] = {}; // Get the distance - //sfeTkError_t err = _theBus->readBlock(kUltrasonicDistanceReadCommand, rawData, numBytes, bytesRead); sfeTkError_t err = _theBus->readRegisterRegion(kUltrasonicDistanceReadCommand, rawData, numBytes, bytesRead); // Check whether the read was successful @@ -92,7 +91,7 @@ sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, address}; //Write the new address to the device - err = _theBus->writeBlock(toWrite, numBytes); + err = _theBus->writeRegion(toWrite, numBytes); } else { //There was some error setting the version in the constructor From d100f66081633123d43e41b7ee045213a571b5c2 Mon Sep 17 00:00:00 2001 From: santised Date: Tue, 18 Jun 2024 15:29:11 -0600 Subject: [PATCH 28/34] Fix to firmware check --- examples/Example2_OLED_Distance/Example2_OLED_Distance.ino | 4 ++-- examples/Example4_ChangeAddress/Example4_ChangeAddress.ino | 5 ++++- src/sfeQwiicUltrasonic.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino index a5500b1..99bf9f5 100644 --- a/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino +++ b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino @@ -24,7 +24,7 @@ #include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" // Create an ultrasonic sensor object -QwiicUltrasonic myUltrasonic(kQwiicUltrasonicFWLatest); +QwiicUltrasonic myUltrasonic; // Creat an OLED object QwiicNarrowOLED myOLED; @@ -80,7 +80,7 @@ void loop() myUltrasonic.getDistance(distance); // Convert distance, which is an integer, to char so that we can print it. - snprintf(distanceBuff, 4, "%d", distance); + snprintf(distanceBuff, 6, "%d", distance); // Put the distance in a string so that we can also print "mm". distanceStr = distanceBuff; diff --git a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino index fb17fb7..ece8606 100644 --- a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino +++ b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino @@ -17,7 +17,10 @@ #include "SparkFun_Qwiic_Ultrasonic_Arduino_Library.h" // Create an ultrasonic sensor object -QwiicUltrasonic myUltrasonic(kQwiicUltrasonicFWLatest); +QwiicUltrasonic myUltrasonic; +// If you're using the older version of the Ultrasonic Distance +// sensor, then uncomment the line below and comment out the line above. +//QwiicUltrasonic myUltrasonic(kQwiicUltrasonicFWOld); // Here we set the device address. Note that an older version of the Qwiic // Ultrasonic firmware used a default address of 0x00. If yours uses 0x00, diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index 3b06d0e..e627ca7 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -40,7 +40,7 @@ class sfeQwiicUltrasonic } /// @brief Default constructor - sfeQwiicUltrasonic(uint8_t fwVersion) : _theBus(nullptr), _fwVersion(fwVersion) + sfeQwiicUltrasonic(const uint8_t fwVersion) : _theBus(nullptr), _fwVersion(fwVersion) { } From 5a368249a1fa32eea3d4933280daa6945d03f5d4 Mon Sep 17 00:00:00 2001 From: santised Date: Tue, 18 Jun 2024 15:51:21 -0600 Subject: [PATCH 29/34] Fixes to comments and some formatting --- .../Example1_BasicReadings.ino | 2 +- .../Example4_ChangeAddress.ino | 2 ++ src/sfeQwiicUltrasonic.cpp | 18 +++++++++--------- src/sfeQwiicUltrasonic.h | 19 ++++++++++++------- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index 0061dd3..78f50d6 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -28,7 +28,7 @@ void setup() { // Start serial Serial.begin(115200); - Serial.println("Ultrasonic Distance Sensor Example 1 - Basic Distance Sensing"); + Serial.println("Ultrasonic Distance Sensor Example 1 - Basic Readings"); Wire.begin(); diff --git a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino index ece8606..113fc87 100644 --- a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino +++ b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino @@ -20,6 +20,8 @@ QwiicUltrasonic myUltrasonic; // If you're using the older version of the Ultrasonic Distance // sensor, then uncomment the line below and comment out the line above. +// You can check the version in copper by the "R" on the front of the board. +// Newer versions are >v10 and older versions simply do not have a version number. //QwiicUltrasonic myUltrasonic(kQwiicUltrasonicFWOld); // Here we set the device address. Note that an older version of the Qwiic diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 40c2fc1..5a26d27 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -19,9 +19,8 @@ sfeTkError_t sfeQwiicUltrasonic::begin(sfeTkII2C *theBus) return kSTkErrFail; // Check the device address - if(_fwVersion == kQwiicUltrasonicFWOld) + if (_fwVersion == kQwiicUltrasonicFWOld) { - if (theBus->address() < kQwiicUltrasonicMinAddress || theBus->address() > kQwiicUltrasonicMaxAddress) { // An older version of the firmware used 0x00 as the default address. @@ -70,7 +69,7 @@ sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) sfeTkError_t err; - if(_fwVersion == kQwiicUltrasonicFWOld) + if (_fwVersion == kQwiicUltrasonicFWOld) { // Old firmware only supports a limited range of addresses. if (address < kQwiicUltrasonicMinAddress || address > kQwiicUltrasonicMaxAddress) @@ -79,7 +78,7 @@ sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) // Write the new address to the device. The first bit must be set to 1 err = _theBus->writeByte(address | 0x80); } - else if(_fwVersion == kQwiicUltrasonicFWLatest) + else if (_fwVersion == kQwiicUltrasonicFWLatest) { size_t numBytes = 2; // Latest firmware versions supports all of the available I2C addresses. @@ -90,13 +89,14 @@ sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) address <<= 1; const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, address}; - //Write the new address to the device + // Write the new address to the device err = _theBus->writeRegion(toWrite, numBytes); } - else { - //There was some error setting the version in the constructor - //return an error. - return kSTkErrOk; + else + { + // There was some error setting the version in the constructor + // return an error. + return kSTkErrFail; } // Check whether the write was successful diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index e627ca7..a7e9072 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -12,12 +12,15 @@ #pragma once #include "SparkFun_Toolkit.h" +#include // Available I2C addresses of the Qwiic Ultrasonic const uint8_t kQwiicUltrasonicDefaultAddress = 0x2F; -const uint8_t kQwiicUltrasonicFWLatest = 0x01; -const uint8_t kQwiicUltrasonicFWOld = 0x10; +// Firmware versions. The later hardware version is v10 and so the "latest" here +// refers to that. The previous version is randomnly given the value v01. +const uint8_t kQwiicUltrasonicFWLatest = 0x10; +const uint8_t kQwiicUltrasonicFWOld = 0x01; // These addresses are the min and max (respectively) of valid I2C addresses that can // be used for the newest revision of the Qwiic Ultrasonic sensor. @@ -35,15 +38,17 @@ class sfeQwiicUltrasonic { public: /// @brief Default constructor + /// sfeQwiicUltrasonic() : _theBus(nullptr), _fwVersion(kQwiicUltrasonicFWLatest) { } - /// @brief Default constructor - sfeQwiicUltrasonic(const uint8_t fwVersion) : _theBus(nullptr), _fwVersion(fwVersion) - { - } - + /// @brief Alternate constructor + /// @param fwVersion Firmware version of the Qwiic Ultrasonic Sensor. If using an older version + /// of the sensor, the list of available I2C addresses differs. + sfeQwiicUltrasonic(const uint8_t fwVersion) : _theBus(nullptr), _fwVersion(fwVersion) + { + } /// @brief Begins the Qwiic Ultrasonic sensor /// @param theBus I2C bus to use for communication From c58db0908ed39f26fbf271e2c12847ac2ee2f503 Mon Sep 17 00:00:00 2001 From: santised Date: Tue, 18 Jun 2024 16:08:58 -0600 Subject: [PATCH 30/34] Adds on more comment --- src/sfeQwiicUltrasonic.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index a7e9072..deb3aa2 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -26,7 +26,8 @@ const uint8_t kQwiicUltrasonicFWOld = 0x01; // be used for the newest revision of the Qwiic Ultrasonic sensor. const uint8_t kQwiicUltrasonicI2CAddressMin = 0x08; const uint8_t kQwiicUltrasonicI2CAddressMax = 0x7F; -// Available I2C addresses of the Qwiic Ultrasonic + +// Available I2C addresses of the older SparkFun Qwiic Ultrasonic Sensor. const uint8_t kQwiicUltrasonicMinAddress = 0x20; const uint8_t kQwiicUltrasonicMaxAddress = 0x2F; ; From c51c6b003a529b2268730abbbd070d924a6d40aa Mon Sep 17 00:00:00 2001 From: santised Date: Tue, 18 Jun 2024 20:21:45 -0600 Subject: [PATCH 31/34] Changes `getDistance()` back to its original name `triggerAndRead()` --- examples/Example1_BasicReadings/Example1_BasicReadings.ino | 2 +- examples/Example2_OLED_Distance/Example2_OLED_Distance.ino | 2 +- src/sfeQwiicUltrasonic.cpp | 2 +- src/sfeQwiicUltrasonic.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino index 78f50d6..abd8da7 100644 --- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino +++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino @@ -45,7 +45,7 @@ void setup() void loop() { uint16_t distance = 0; - myUltrasonic.getDistance(distance); + myUltrasonic.triggerAndRead(distance); // Print measurement Serial.print("Distance (mm): "); diff --git a/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino index 99bf9f5..4767e69 100644 --- a/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino +++ b/examples/Example2_OLED_Distance/Example2_OLED_Distance.ino @@ -77,7 +77,7 @@ void setup() void loop() { uint16_t distance = 0; - myUltrasonic.getDistance(distance); + myUltrasonic.triggerAndRead(distance); // Convert distance, which is an integer, to char so that we can print it. snprintf(distanceBuff, 6, "%d", distance); diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 5a26d27..5b7d6dd 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -43,7 +43,7 @@ sfeTkError_t sfeQwiicUltrasonic::isConnected() return _theBus->ping(); } -sfeTkError_t sfeQwiicUltrasonic::getDistance(uint16_t &distance) +sfeTkError_t sfeQwiicUltrasonic::triggerAndRead(uint16_t &distance) { size_t bytesRead; size_t numBytes = 2; diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index deb3aa2..843ea3d 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -63,7 +63,7 @@ class sfeQwiicUltrasonic /// @brief Triggers a new measurement and reads the previous one /// @param distance Distance in mm /// @return 0 for succuss, negative for errors, positive for warnings - sfeTkError_t getDistance(uint16_t &distance); + sfeTkError_t triggerAndRead(uint16_t &distance); /// @brief Changes the I2C address of older Qwiic Ultrasonic sensors. /// @param address New address, must be in the range 0x20 to 0x2F From 8668f36246446d0630f2c2e87f26520dd33afe06 Mon Sep 17 00:00:00 2001 From: santised Date: Tue, 18 Jun 2024 20:28:06 -0600 Subject: [PATCH 32/34] Removes erroneous include --- src/sfeQwiicUltrasonic.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sfeQwiicUltrasonic.h b/src/sfeQwiicUltrasonic.h index 843ea3d..f8942da 100644 --- a/src/sfeQwiicUltrasonic.h +++ b/src/sfeQwiicUltrasonic.h @@ -12,7 +12,6 @@ #pragma once #include "SparkFun_Toolkit.h" -#include // Available I2C addresses of the Qwiic Ultrasonic const uint8_t kQwiicUltrasonicDefaultAddress = 0x2F; From 4578da408213df46738e38cc1922354c9d1c9b6c Mon Sep 17 00:00:00 2001 From: Elias Santistevan Date: Fri, 21 Jun 2024 08:18:24 -0600 Subject: [PATCH 33/34] Fixes error when writing new address to the ultrasonic object forcing an unnecessary reload * Updates example four to continue with reading distance at the changed address. --- .../Example4_ChangeAddress.ino | 25 ++++++++++++++----- src/sfeQwiicUltrasonic.cpp | 8 +++--- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino index 113fc87..f91af34 100644 --- a/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino +++ b/examples/Example4_ChangeAddress/Example4_ChangeAddress.ino @@ -66,6 +66,7 @@ void setup() // Call change address..... sfeTkError_t err = myUltrasonic.changeAddress(newAddr); + if(err) { while(1) @@ -75,16 +76,28 @@ void setup() delay(1000); } } - delay(1000); - Serial.print("Load up example 1 with the new address at: "); - Serial.println(newAddr, HEX); - Serial.println("Freezing...."); - while(1) - ; + Serial.println("Address changed successfully!"); + Serial.println("Reading Distance at new address......"); + delay(3000); } void loop() { + uint16_t distance = 0; + myUltrasonic.triggerAndRead(distance); + + // Print measurement + Serial.print("Distance (mm): "); + Serial.println(distance); + + //Serial.println("Distance (cm): "); + //Serial.print((distance / 10.0), 2); + + //Serial.println("Distace (in): "); + //Serial.print((distance / 25.4), 2); + + // Wait a bit + delay(100); } diff --git a/src/sfeQwiicUltrasonic.cpp b/src/sfeQwiicUltrasonic.cpp index 5b7d6dd..e3a1f48 100644 --- a/src/sfeQwiicUltrasonic.cpp +++ b/src/sfeQwiicUltrasonic.cpp @@ -86,8 +86,8 @@ sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) return kSTkErrFail; // We want to shift the address left before we send it. - address <<= 1; - const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, address}; + uint8_t tempAddress = address << 1; + const uint8_t toWrite[2] = {kUltrasonicAddressChangeCommand, tempAddress}; // Write the new address to the device err = _theBus->writeRegion(toWrite, numBytes); @@ -99,13 +99,11 @@ sfeTkError_t sfeQwiicUltrasonic::changeAddress(uint8_t &address) return kSTkErrFail; } + _theBus->setAddress(address); // Check whether the write was successful if (err != kSTkErrOk) return err; - // Update the address in the bus - _theBus->setAddress(address); - // Done! return kSTkErrOk; } From 2278ae68911cc9f044d268f4f7c956becf22f57b Mon Sep 17 00:00:00 2001 From: loricrotser <34865493+loricrotser@users.noreply.github.com> Date: Fri, 21 Jun 2024 08:21:24 -0600 Subject: [PATCH 34/34] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9deb9e1..898a061 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,16 @@ - + - SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 + SparkFun Ultrasonic Distance Sensor - TCT40 (Qwiic) -You may be familiar with the classic [HC-SR04 distance sensor](https://www.sparkfun.com/products/15569), it is great for providing non-contact distance readings from 2cm to 400cm. The SparkFun Qwiic Ultrasonic Distance Sensor improves on the classic by adding a pair of Qwiic connectors to it, so now you can communicate over I2C and daisy chain any other Qwiic product of your choosing. +The SparkFun Qwiic Ultrasonic Distance Sensor, a user-friendly upgrade to the popular HC-SR04 sensor, offers non-contact distance measurement from 2cm to 400cm with an accuracy of 3mm. This sensor is designed to seamlessly integrate with the Qwiic ecosystem for I2C communication, making it a breeze to add to your existing projects and daisy-chain with other Qwiic components. -If you prefer to bypass the Qwiic connector and I2C you can also access the VCC, Trigger, Echo, and Ground pins broken out on the edge of the board. Please be aware that this ultrasonic sensor comes uncalibrated and you will need manipulate the raw output for your specific application. +With its wide range of applications, the SparkFun Qwiic Ultrasonic Distance Sensor is a versatile tool for robotics projects, obstacle avoidance systems, and any application that requires accurate distance measurement without physical contact. Its adaptability makes it a valuable addition to your toolkit. Repository Contents ------------------- @@ -27,8 +27,8 @@ Repository Contents Documentation -------------- -* **[GitHub Repo](https://github.com/sparkfun/Zio-Qwiic-Ultrasonic-Distance-Sensor)** - GitHub repo for the SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04 Hardware Files. -* **[Hookup Guide](https://learn.sparkfun.com/tutorials/qwiic-ultrasonic-distance-sensor-hc-sr04-hookup-guide)** - Basic hookup guide for the SparkFun Qwiic Ultrasonic Distance Sensor - HC-SR04. +* **[GitHub Repo](https://github.com/sparkfun/SparkFun_Ultrasonic_Distance_Sensor-Qwiic/tree/v11_Firmware_v01)** - GitHub repo for the SparkFun Ultrasonic Distance Sensor - TCT40 (Qwiic) Hardware Files. +* **[Hookup Guide](https://docs.sparkfun.com/SparkFun_Ultrasonic_Distance_Sensor-Qwiic/)** - Basic hookup guide for the SparkFun Ultrasonic Distance Sensor - TCT40 (Qwiic). License Information -------------------