What kind of displays do you use is not these? Graphical? I have a ili9341 laying around maybe i can adapt the code
Can someone explain me the thread.delay() function? And what if I woul use delay instead of thread.delay()? Woul it stop both threads?
0=0cm 1=13cm 2=21cm 3=44cm
0=0cm 1=0cm 2=20cm 3=45cm
0=16cm 1=0cm 2=21cm 3=45cm
0=16cm 1=999cm 2=0cm 3=29cm
0=16cm 1=13cm 2=0cm 3=39cm
#include <Arduino.h>
#include "Threads.h"
#include <NewPing.h>
#define SONAR_NUM 4 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 45 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
NewPing sonar[SONAR_NUM] = { // Sensor object array.
NewPing(27, 26, MAX_DISTANCE), //lower left sensor
NewPing(36, 35, MAX_DISTANCE), //front middle
NewPing(30, 29, MAX_DISTANCE), //lower rigth sensro
NewPing(34, 33, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
};
int id1, id2, id3;
volatile int p1 = 0;
volatile int p2 = 0;
volatile int p3 = 0;
#define delayx delay
void my_priv_func1(){
while(1){
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
currentSensor = i; // Sensor being accessed.
cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
}
}
//threads.yield();
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(5000);
pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
// put your main code here, to run repeatedly:
Serial.print("Thread start ");
id1 = threads.addThread(my_priv_func1,1);
if (threads.getState(id1) == Threads::RUNNING) Serial.println("OK");
}
void echoCheck() { // If ping received, set the sensor distance to array.
if (sonar[currentSensor].check_timer()){
cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
} else {
cm[currentSensor] = 999;
}
}
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
for (uint8_t i = 0; i < SONAR_NUM; i++) {
Serial.print(i);
Serial.print("=");
Serial.print(cm[i]);
Serial.print("cm ");
}
Serial.println();
}
void loop() {
}
Thread start OK
0=200cm 1=15cm 2=15cm 3=19cm
0=21cm 1=15cm 2=16cm 3=18cm
0=21cm 1=15cm 2=15cm 3=18cm
0=21cm 1=15cm 2=15cm 3=18cm
0=21cm 1=15cm 2=16cm 3=18cm
#include <Arduino.h>
#include "Threads.h"
#include <NewPing.h>
#define SONAR_NUM 4 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 45 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
NewPing sonarll(27, 26, MAX_DISTANCE); //lower left sensor
NewPing sonarlc(36, 35, MAX_DISTANCE); //front middle
NewPing sonarlr(30, 29, MAX_DISTANCE); //lower rigth sensro
NewPing sonarhd(34, 33, MAX_DISTANCE); // Each sensor's trigger pin, echo pin, and max distance to ping.
int id1, id2, id3;
volatile int p1 = 0;
volatile int p2 = 0;
volatile int p3 = 0;
#define delayx delay
void my_priv_func1(){
while(1){
cm[0] = 0;
unsigned int uS = sonarll.ping();
//unsigned int uS = sonarll.ping_median();
cm[0] = uS / US_ROUNDTRIP_CM;
threads.delay(PING_INTERVAL);
cm[1] = 0;
uS = sonarlc.ping();
//uS = sonarlc.ping_median();
cm[1] = uS / US_ROUNDTRIP_CM;
threads.delay(PING_INTERVAL);
cm[2] = 0;
uS = sonarlr.ping();
//uS = sonarlr.ping_median();
cm[2] = uS / US_ROUNDTRIP_CM;
threads.delay(PING_INTERVAL);
cm[3] = 0;
uS = sonarhd.ping();
uS = sonarhd.ping_median();
cm[3] = uS / US_ROUNDTRIP_CM;
threads.delay(PING_INTERVAL);
for (uint8_t i = 0; i < SONAR_NUM; i++) {
if(cm[i] == 0) cm[i] = MAX_DISTANCE;
}
oneSensorCycle();
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(5000);
Serial.print("Thread start ");
id1 = threads.addThread(my_priv_func1,1);
if (threads.getState(id1) == Threads::RUNNING) Serial.println("OK");
}
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
for (uint8_t i = 0; i < SONAR_NUM; i++) {
Serial.print(i);
Serial.print("=");
Serial.print(cm[i]);
Serial.print("cm ");
}
Serial.println();
}
void loop() {
}
Any suggestions for making this more efficient would be appreciated.
#include <Arduino.h>
#include "Threads.h"
#include <NewPing.h>
#include <Streaming.h>
#include <vector>
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
/* Set the delay between fresh samples for BNO055*/
#define BNO055_SAMPLERATE_DELAY_MS (100)
Adafruit_BNO055 bno = Adafruit_BNO055(55);
float yar_heading, pitch, roll;
#define telem Serial
#define SONAR_NUM 4 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 45 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
NewPing sonarll(27, 26, MAX_DISTANCE); //lower left sensor
NewPing sonarlc(36, 35, MAX_DISTANCE); //front middle
NewPing sonarlr(30, 29, MAX_DISTANCE); //lower rigth sensro
NewPing sonarhd(34, 33, MAX_DISTANCE); // Each sensor's trigger pin, echo pin, and max distance to ping.
//IR Sensor Pins
const int leftIRsensor = A22; //Front
const int rightIRsensor = A2; //Rear
int frtIRdistance, rearIRdistance;
int max_IR_distance = 200;
int id1, id2, id3;
void my_priv_func1(){
while(1){
cm[0] = 0;
unsigned int uS = sonarll.ping();
//unsigned int uS = sonarll.ping_median();
cm[0] = uS / US_ROUNDTRIP_CM;
threads.delay(PING_INTERVAL);
cm[1] = 0;
uS = sonarlc.ping();
//uS = sonarlc.ping_median();
cm[1] = uS / US_ROUNDTRIP_CM;
threads.delay(PING_INTERVAL);
cm[2] = 0;
uS = sonarlr.ping();
//uS = sonarlr.ping_median();
cm[2] = uS / US_ROUNDTRIP_CM;
threads.delay(PING_INTERVAL);
cm[3] = 0;
uS = sonarhd.ping();
//uS = sonarhd.ping_median();
cm[3] = uS / US_ROUNDTRIP_CM;
threads.delay(PING_INTERVAL);
for (uint8_t i = 0; i < SONAR_NUM; i++) {
if(cm[i] == 0) cm[i] = MAX_DISTANCE;
}
}
}
void my_priv_func2(){
while(1){
int sum = 0;
for (int i=0; i<3; i++) {
int sensor_value = analogRead(leftIRsensor); //read the sensor value
if(sensor_value < 100){
sensor_value = 100;
}
sum = sum + sensor_value;
threads.delay(5);
}
frtIRdistance = 27495 * pow(sum/3,-1.36); //convert readings to distance(cm)
sum = 0;
for (int i=0; i<3; i++) {
int sensor_value = analogRead(rightIRsensor); //read the sensor value
if(sensor_value < 100){
sensor_value = 100;
}
sum = sum + sensor_value;
threads.delay(5);
}
rearIRdistance = 25445 * pow(sum/3,-1.362); //convert readings to distance(cm)
}
}
void my_priv_func3(){
while(1){
sensors_event_t event;
bno.getEvent(&event);
imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);
roll = (float)event.orientation.y;
pitch = (float)event.orientation.z;
yar_heading = (float)event.orientation.x;
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin(400000);
BNO055_Init();
delay(5000);
Serial.print("Thread start ");
id1 = threads.addThread(my_priv_func1,1);
id2 = threads.addThread(my_priv_func2,1);
id3 = threads.addThread(my_priv_func3,1);
if (threads.getState(id1) == Threads::RUNNING) Serial.println("Sonar thread started");
if (threads.getState(id2) == Threads::RUNNING) Serial.println("IR thread started");
if (threads.getState(id3) == Threads::RUNNING) Serial.println("BNO055 thread started");
}
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
for (uint8_t i = 0; i < SONAR_NUM; i++) {
Serial.print(i);
Serial.print("=");
Serial.print(cm[i]);
Serial.print("cm ");
}
Serial.println();
telem << "IR Distances: " << frtIRdistance << " -- " << rearIRdistance << endl;
telem << -roll << "," << -pitch << "," << yar_heading << endl;
}
void loop() {
oneSensorCycle();
}
I used IntervalTimer. I wouldn't use the PIT directly (to minimize conflicts with other code wanting to use the timers).@tni, how did you implement the 100us ticks? I looked at using IntervalTimer (or directly the PIT timer) but maybe there is a better way.
The change is pretty trival. I renamed "systick_isr" in thread.cpp and removed the systick increment:@tni, would you mind sharing your code so other (including me) can try it?
//void __attribute((naked)) systick_isr(void)
void __attribute((naked)) ctx_switch_timer_isr(void) {
//systick_millis_count++;
IntervalTimer ctx_switch_timer;
extern void ctx_switch_timer_isr();
void setup() {
ctx_switch_timer.begin(ctx_switch_timer_isr, 100);
...