Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
dfa4407
First Commit
niiquaye Jan 1, 2021
25e2a46
Merge branch 'master' into orson/createURM04Driver
niiquaye Jan 1, 2021
d3ed65d
Second Commit - More Updates
niiquaye Jan 3, 2021
1e3cc25
Merge branch 'orson/createURM04Driver' of https://github.com/uwroboti…
niiquaye Jan 3, 2021
5696acc
Third-Commit
niiquaye Jan 3, 2021
fe2c004
Fourth Commit - Younes' Requested Changes
niiquaye Jan 3, 2021
a279500
Fifth Commit - Younes' Updated Requested Changes
niiquaye Jan 3, 2021
dd18b99
Sixth Commit - Younes' Updated Request Changes Pt2.
niiquaye Jan 4, 2021
631162c
Seventh Commit - Cindy's Requested Changes
niiquaye Jan 4, 2021
5a62e19
Eigth Commit - Cindy's Requested Changes (Updated Constructor) PT2
niiquaye Jan 4, 2021
30ef990
Ninth Commit - Added RS485 TX/RX Mode with TriggerPin
niiquaye Jan 4, 2021
c4541c0
Ninth Commit PT2 - Error checking for when distance read is out of range
niiquaye Jan 4, 2021
b321611
Tenth Commit - Added Cindy's Requested Changes
niiquaye Jan 10, 2021
99c8d4d
Minor Changes to Constructor/ Serial Communication / Command Buffer -…
niiquaye Jan 12, 2021
162e05c
Minor Changes to Constructor/ Serial Communication / Command Buffer -…
niiquaye Jan 12, 2021
ad2999b
Merge branch 'master' into orson/createURM04Driver
niiquaye Jan 12, 2021
a5693c7
Merge branch 'orson/createURM04Driver' of https://github.com/uwroboti…
niiquaye Jan 12, 2021
c3dd8b5
Merge branch 'orson/createURM04Driver' of https://github.com/uwroboti…
niiquaye Jan 12, 2021
26ffa55
Merge branch 'orson/createURM04Driver' of https://github.com/uwroboti…
niiquaye Jan 12, 2021
6b303be
Merge branch 'orson/createURM04Driver' of https://github.com/uwroboti…
niiquaye Jan 12, 2021
9c9aa6b
Fixing Git Issues
niiquaye Jan 12, 2021
8caefc5
Removed Flushing the Serial buffer - Cindy's Requested Changes
niiquaye Jan 12, 2021
660e32a
Merge branch 'orson/createURM04Driver' of https://github.com/uwroboti…
niiquaye Jan 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ add_subdirectory(lib/pid)
add_subdirectory(lib/sensors)
add_subdirectory(lib/servo)


if (NOT DEFINED APP)
message(FATAL_ERROR "APP variable not set in CACHE. Please invoke CMake with \"-DAPP=<app-name>\"")
elseif (NOT EXISTS "${CMAKE_SOURCE_DIR}/apps/${APP}")
Expand Down Expand Up @@ -172,3 +173,4 @@ add_subdirectory(apps/test-moisture)
add_subdirectory(apps/test-pid)
add_subdirectory(apps/test-pwm)
add_subdirectory(apps/test-pwmin)
add_subdirectory(apps/test-urm04)
1 change: 1 addition & 0 deletions apps/test-pwm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
add_executable(test-pwm.${TARGET}-board.elf)
target_sources(test-pwm.${TARGET}-board.elf PRIVATE src/main.cpp)
target_set_firmware_properties(test-pwm.${TARGET}-board.elf)

4 changes: 4 additions & 0 deletions apps/test-urm04/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add_executable(test-urm04.${TARGET}-board.elf)
target_sources(test-urm04.${TARGET}-board.elf PRIVATE src/main.cpp)
target_link_libraries(test-urm04.${TARGET}-board.elf PRIVATE URM04Sensor uwrt-mars-rover-hw-bridge)
target_set_firmware_properties(test-urm04.${TARGET}-board.elf)
13 changes: 13 additions & 0 deletions apps/test-urm04/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "URM04Sensor.h"
int main() {
// D2 - trigpin
// D1 - TX
// D0 - RX
sensor::URM04Sensor sensor(D2, D0, D1);
while (1) {
sensor.read();
sensor.print_distance();
ThisThread::sleep_for(std::chrono::milliseconds(10));
}
return 0;
}
5 changes: 5 additions & 0 deletions lib/sensors/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ add_library(QEI STATIC)
target_sources(QEI PRIVATE src/QEI.cpp)
target_include_directories(QEI PUBLIC include)
target_set_mbed_dependency(QEI)

add_library(URM04Sensor STATIC)
target_sources(URM04Sensor PRIVATE src/URM04Sensor.cpp)
target_include_directories(URM04Sensor PUBLIC include)
target_set_mbed_dependency(URM04Sensor)
61 changes: 61 additions & 0 deletions lib/sensors/include/URM04Sensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once

#include "mbed.h"

namespace sensor {

class URM04Sensor {
protected:
// constants
static constexpr int urmAccount = 1;
static constexpr int MAX_TRIES = 10;
static constexpr int BAUD_RATE = 19200;
static constexpr int START_ADDRESS = 0x11;
static constexpr int LOW = 0;
static constexpr int HIGH = 1;

private:
// trigger pin
DigitalOut m_trigPin;
// start address
uint8_t startAddr;
// command buffer
uint8_t cmdst[10];
// state machine reading step
uint8_t readingStep;
// arrays needed to read and write distance from sensor
int urmID[urmAccount];
uint32_t urmData[urmAccount];
// timer related members
uint64_t managerTimer;
Timer clock;
// UART protocol pins
PinName RX;
PinName TX;
// successful read
bool read_success;

// trigger the mesausrements from URM04
void urmTrigger(int id);
// reads the distance from URM04
void urmReader(int id);
// transmit commands
void transmitCommands();

// analyzes the distance**
void analyzeUrmData(uint8_t cmd[]);
// runs the sensor - starts giving commands to the sensor
void runUrm04();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does it mean to run the sensor?

// decodes URM04 data
void decodeURM04();

public:
// constructor
URM04Sensor(PinName trig_pin, PinName _RX, PinName _TX);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cindyli-13 what are the trig_pins on the pdb? i didnt see em in the ioc?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PDB doesn't have the trig pin, it just has RX and TX signals. I think the arduino example this driver is based off of had that extra trig pin, so it's a bit different for us.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I checked over the PCB design again and we might need to do some rework to add the "trig pin". I think I made a mistake with the design and the trig signal is needed, sorry about that.

// destructor
~URM04Sensor();
bool read();
void print_distance();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rmeove the print_distance function. this introduces a dependency on our uart which makes the lib less general

};

} // namespace sensor
197 changes: 197 additions & 0 deletions lib/sensors/src/URM04Sensor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
#include "URM04Sensor.h"

// instantiate pin connected to the URM04 sensor
sensor::URM04Sensor::URM04Sensor(PinName trig_pin, PinName _RX, PinName _TX)
: m_trigPin(trig_pin), startAddr(START_ADDRESS), readingStep(LOW), RX(_RX), TX(_TX), read_success(false) {
// start timer
clock.start();
// get start time
managerTimer = clock.read_ms();

// write low to pin to start instructions
m_trigPin.write(LOW);

// Initialize urm04 command recieving address
for (int i{0}; i < urmAccount; i++) {
urmID[i] = startAddr + 1;
urmData[i] = 0;
}

// initialise commands - set zero everywhere
for (int i{0}; i < 10; i++) {
cmdst[i] = 0;
}

// initialize urm04 protocol
cmdst[0] = 0x55;
cmdst[1] = 0xaa;

// set nucleo_board baud rate

// set up serial communication uart bufferserial with baud rate
// serial communication - D1/TX , D0/RX,
BufferedSerial nucleo_board(TX, RX, BAUD_RATE);
}
// destructor
sensor::URM04Sensor::~URM04Sensor() {
// kill the timer
clock.stop();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does the destructor of the timer class do? it might already do this. if so, delete the destructor. you can find this out by right clicking the timer class and clicking go to definition. you could also google mbed os timer class

}
// trigger the measurements
void sensor::URM04Sensor::urmTrigger(int id) {
// fill the command buffer with trigger commands
cmdst[2] = id;
cmdst[3] = 0x00;
cmdst[4] = 0x01;
// send command over serial
transmitCommands();
}
// reads the distance from URM04
void sensor::URM04Sensor::urmReader(int id) {
// fill command buffer with read commands
cmdst[2] = id;
cmdst[3] = 0x00;
cmdst[4] = 0x02;
// send command over serial
transmitCommands();
}
// transmit commands
void sensor::URM04Sensor::transmitCommands() {
cmdst[5] = cmdst[0] + cmdst[2] + cmdst[3] + cmdst[4];
// delay for 1 second using thread 1000ms = 1sec
ThisThread::sleep_for(std::chrono::milliseconds(1000));
// send command over serial connection with BufferedSerial write and put into cmdst
nucleo_board.write(&cmdst[0], sizeof(cmdst));
// delay for 2 seconds 2000ms = 2sec
ThisThread::sleep_for(std::chrono::milliseconds(2000));
}

// this function actually gets the data
void sensor::URM04Sensor::analyzeUrmData(uint8_t cmd[]) {
uint8_t checkSum = 0;
// add each byte in the command array to create checksum
for (int i{0}; i < 7; i++) {
checkSum += cmd[i];
}
// check is checksum is correct and that the commands are correct as well
if (checkSum == cmd[7] && cmd[3] == 2 && cmd[4] == 2) {
uint8_t id = cmd[2] - startAddr;
urmData[id] = cmd[5] * 256 + cmd[6];
}
// else an error occured during transmission
else if (cmd[3] == 2 && cmd[4] == 2) {
read_success = false;
}
}

// decodes URM04 data
void sensor::URM04Sensor::decodeURM04() {
// make sure serial is still running
if (nucleo_board.readable()) {
// timer
int timerPoint = clock.read_ms();
// counter
int RetryCounter{0};
// array to hold commands
uint8_t cmdrd[10];
// fill the array
for (int i{0}; i < 10; i++) {cmdrd[i] = 0;}
// start index & indices
int indices{0};
int start_index{0};
// flag to check if the indices in the buffer are valid
bool flag{true};
// variable to check if the whole buffer is valid
bool valid{false};
// header bit
uint8_t headerNo{0};

while (RetryCounter < MAX_TRIES && flag) {
// ensure serial is still running
if (nucleo_board.available()) {
// read from the serial port with BufferedSerial read and put data into cmdrd
indices = nucleo_board.read(cmdrd, sizeof(cmdrd));
// did not read from serial port properly
if (indices == -1) {
flag = false;
// flush buffer
nucleo_board.sync();
// read failed
read_success = false;
break; // exit loop
}
// confirm the header address is correct
if (cmdrd[start_index] == 0xAA) {
headerNo = 1;
valid = true;
}
// confirm every bit is within the range of the buffer
if (valid && start_index == headerNo + 6) {
flag = false;
break; // exit loop
}

start_index++;
RetryCounter = 0;

} else {
RetryCounter++;
ThisThread::sleep_for(std::chrono::microseconds(15));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thisthread api doesnt work for microseconds. use wait_us(15) instead

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where did u get all your wait values from? arduino code?

}
}
// since all the data has proven to be valid send the data to be analyzed
if (valid) {
read_success = true;
analyzeUrmData(cmdrd);
}
}
}
// run the urm04
void sensor::URM04Sensor::runUrm04() {
static uint64_t timer{0};
static int num{0};

if ((uint64_t)clock.read_ms() - timer > managerTimer) {
// write high to trip pin to turn on RS485 Transmitting mode
m_trigPin.write(1);

// state machine to read measurements from the sensor
switch (readingStep) {
case 0:
urmTrigger(urmID[num]);
managerTimer = 40; // set interval for timed measurement after triggering measurements
break;
case 1:
urmReader(urmID[num]);
managerTimer = 0; // set interval for measurements after reading distance command
break;
case 2:
m_trigPin.write(LOW); // turn on reading mode for RS485
managerTimer = 10;
break;
default:
readingStep = 0;
break;
}

if (readingStep < 2)
readingStep++;
else
readingStep = 0;

timer = clock.read_ms();
}
}
// this function runs the sensor
bool sensor::URM04Sensor::read() {
runUrm04();
decodeURM04();
return read_success;
}
// this function prints the data from the sensor
void sensor::URM04Sensor::print_distance() {
for (int i{0}; i < urmAccount; i++) {
printf("Distance: %u\n", urmData[i]);
}
ThisThread::sleep_for(std::chrono::milliseconds(100));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just write 100ms

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this wait here. is it to slow down the loop inside the test app? if so dont do that.

}
3 changes: 3 additions & 0 deletions supported_build_configurations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,6 @@ test-pwmin:
# - gamepad
# - gimbtonomy
# - science

test-urm04:
- nucleo