C++ Void Call Timeout - c++

I`ve got a problem with my C++ application on a Raspberry Pi. This script should print a distance in cm one time before terminatig. But it should also check if the ultrasonic sensor is connected and if not the script should break. How could I do that? Is there a way to set a timeout for the getCM() method or has anyone another idea to solve this?
This is the code:
...
void setup() {
wiringPiSetup();
pinMode(TRIG_R, OUTPUT);
pinMode(ECHO_R, INPUT);
digitalWrite(TRIG_F, LOW);
delay(30);
}
int getCM() {
digitalWrite(TRIG_R, HIGH);
delayMicroseconds(20);
digitalWrite(TRIG_R, LOW);
//Wait for echo start
while(digitalRead(ECHO_R) == LOW);
//Wait for echo end
long startTime = micros();
while(digitalRead(ECHO_R) == HIGH);
long travelTime = micros() - startTime;
int distance = travelTime / 58;
return distance;
}
int main(void) {
setup();
printf("Distance: %dcm\n", getCM());
return 0;
}
Thanks in advance!
Tim

Checking in advance for the ultrasonic sensor there's not much anyone can suggest without knowing more about the sensor. If the communication is purely bit-toggling you probably can't tell without more hardware.
For the second part, timing out getCM, add an extra condition to the digitalRead loops to force an exit. For example:
int timeout = <read timeout goes here>;
while((digitalRead(ECHO_R) == LOW)&&(--timeout));
if (!timeout)
{
return -1; // Should never be able to read less than blanking distance
// from an ultrasonic sensor. -1 is certainly out of range.
}
In main you can either print out the -1 or check for -1 and print out a better error message. For more clarity, the second loop could return -2; on failure so you know what failed.

Related

How to count milliseconds on the Raspberry Pi Pico?

I want to count milliseconds on my Pico to make nonblocking code in C++.
Arduino has the millis() function, but after looking though all the example programs and scouring the internet I couldn't find anything like that for the Pico using C++.
This is the BlinkWithoutDelay sketch from the Arduino examples that shows what I want to do:
const int ledPin = LED_BUILTIN;// the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const long interval = 1000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
I decided to go with a repeating timer as suggested by some comments and the examples that used it really difficult to understand for me. So I'll try to explain it the best I can.
*Note that I don't really understand some of the values being passed into functions but I know enough to make this work. Please feel free to correct me
#include "pico/stdlib.h"
bool led_state;
//Function Called by the timer
bool timer_callback( repeating_timer_t *rt )
{
//Blinks the LED
led_state = !led_state;
gpio_put(25, led_state);
return (true);
}
int main(){
//From what I can tell this creates an identifier for the timer
static repeating_timer_t timer;
stdio_init_all();
//GPIO setting (GPIO_25 is the LED pin on the pico)
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
//Sets a repeating timer to call a function every 1000 milliseconds
//add_repeating_timer_ms( int interval_in_milliseconds, ?&function to call?, ???, ?timer identifier? );
add_repeating_timer_ms( 1000, &timer_callback, NULL, &timer );
while(true){
//Blinks LED briefly at a different interval than the repeating timer
//This is to show that my code isn't blocked
gpio_put(25, !led_state);
sleep_ms(50);
gpio_put(25, led_state);
sleep_ms(450);
}
return 0;
}

Arduino loop does not stop - only with smaller counters. Arduino Nano Every

I cannot explain to myself why this code works properly in some cases and in some not. Here is the situation:
I am trying to switch a relay with the Arduino Nano. Therefore I took the "Blink" example as a guide. It should switch on for like 5 minutes and switch off for like 25 minutes. Here is the code:
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(2, OUTPUT); // sets PIN 2 as switcher for the relay
}
// the loop function runs over and over again forever
void loop() {
int count = 0;
int run_pump = 300; // 5 Min run
int stop_pump = 1500; // 25 Min stop
digitalWrite(LED_BUILTIN, LOW); // turn the LED off (HIGH is the voltage level)
digitalWrite(2, HIGH); // turn the pump on
while(count < run_pump) {
count++;
delay(1000); // wait for a second
}
count = 0;
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on by making the voltage LOW
digitalWrite(2, LOW); // turn the pump off
while(count < stop_pump) {
count++;
delay(1000); // wait for a second
}
}
if I run this code on the Arduino it will just switch on the relay forever. BUT: If I set run_pump and stop_pump for like 10 sec. it will work properly! Is there an explanation why this does not work with the bigger counters? It's so confusing....
so this code here works absolutely fine, but why does the code above not?
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(2, OUTPUT); // sets PIN 2 as switcher for the relay
}
// the loop function runs over and over again forever
void loop() {
int count = 0;
int run_pump = 5; // 5 sec run
int stop_pump = 10; // 10 sec stop
digitalWrite(LED_BUILTIN, LOW); // turn the LED off (HIGH is the voltage level)
digitalWrite(2, HIGH); // turn the pump on
while(count < run_pump) {
count++;
delay(1000); // wait for a second
}
count = 0;
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on by making the voltage LOW
digitalWrite(2, LOW); // turn the pump off
while(count < stop_pump) {
count++;
delay(1000); // wait for a second
}
}
Hope someone has a clue.... Thanks!
Tom
OK guys, I solved it. The problem was a cheap relay that was trying to communicate with the Arduino... Replacing it with a better one solved the whole problem. Thanks for the idea with the LED, this brought some stones to roll... :)

C++ (Particle Photon) Threading with changing variable

Note: The code is designed to run on a Particle Photon. Please keep this in mind while reading my question.
I want to make a led blink based on a variable called blink_type this variable will be changed dynamically in a later stage when I implement the API call to fetch the status of something else. I'm currently simulating this behaviour in the loop() function (also tried a thread but that also didn't work).
The blinking works fine until the variable changes from 0 to 1, after that it never blinks again until I do a reset.
Below you will find my code:
// This #include statement was automatically added by the Particle IDE.
#include <httpsclient-particle.h>
// Base variables.
int led = D0;
int buzzer = D1;
// Defining blink types. 0 is normal, 1 is breathe.
int blink_type = 0;
// Set the threads
Thread *normalBlinkThread;
Thread *ledBreatherThread;
void setup() {
// Setup the outputs.
pinMode(led, OUTPUT);
pinMode(buzzer, OUTPUT);
// Create the required threads.
normalBlinkThread = new Thread("rest_status_light", normalBlink);
ledBreatherThread = new Thread("rest_status_light", hearthBeatBlink);
}
os_thread_return_t normalBlink(void*) {
// Start never ending loop
for(;;) {
if(blink_type == 0) {
// Blink led
digitalWrite(led, HIGH);
delay(3000);
digitalWrite(led, LOW);
delay(3000);
}
}
}
os_thread_return_t hearthBeatBlink(void*) {
// Start never ending loop
for(;;) {
if(blink_type == 1) {
// Blink led
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
delay(500);
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
delay(3000);
}
}
}
void loop() {
delay(10000);
switch (blink_type) {
case 0:
blink_type = 1;
break;
case 1:
blink_type = 0;
break;
}
}
To not get confused, the "buzzer" output (D1) is currently also wired to an LED.
If there would be a better approach to blink a led in two different ways based on a dynamic variable I'm happy to adopt to this sollution!
normalBlink() and hearthBeatBlink() have delays only when (blink_type == 1). When blink_type becomes 0 there are no delays in the for loops and one of them, the first which evaluates the variable change, happily spins for eternity. Try to add a small delay in the case blink_type is 0. Hope this helps!

Arduino Uno to Particle Photon - Converting Code

Please bear with me. I am an amateur programmer at Arduino, and have never used Particle photon before.
I used an Arduino Uno and wrote the attached code that detects heart beat and temperature using the Grove Ear clip heart beat sensor and the Grove Temperature sensor and then prints them in the console every 20 seconds. Previously, this code was written to show in an Grove OLED screen but later simplified it back to using it without the OLED screen.
I am now looking into using the same application and function using the same sensor on a Particle Photon (as it is smaller and has WiFi capability). I have never previously used this technology before but I saw online that it, more or less, uses the same code application. I have been through the sample codes for this online available on its website but I have no idea how to convert my code for the Arduino into code for the photon (Photon console compiles the code without any error but does not show any sensor data). Can someone either point me to the right direction/ appropriate online resources / help me change this code here to make it work on the Photon? (I just added the Particle.publish() wherever I was using Arduino's Serial.println() but it still doesn't print anything).
The result in the console shows:
Please be ready
This will now begin
then it prints number 1 to 20 every second followed by sensor readings.
Again sorry for the inconvenience and thank you for your help.
I used direct codes from the documentation blog of the sensors (bottom of the page of the linked page):
Grove heart bear sensor
Grove Temperature sensor
#define LED 4//indicator, Grove - LED is connected with D4 of Arduino
boolean led_state = LOW;//state of LED, each time an external interrupt
//will change the state of LED
float tempa;
int tempPin = 0;
unsigned char counter;
unsigned long temp[21];
unsigned long sub;
bool data_effect=true;
unsigned int heart_rate;//the measurement result of heart rate
const int max_heartpluse_duty = 2000;//you can change it follow your system's request.
//2000 meams 2 seconds. System return error
//if the duty overtrip 2 second.
void setup()
{
pinMode(LED, OUTPUT);
Serial.begin(9600);
while (!Serial){
;
}
Serial.println("Please be ready");
delay(5000);
arrayInit();
Serial.println("This will now begin.");
attachInterrupt(0, interrupt, RISING);//set interrupt 0,digital port 2
}
void loop()
{
digitalWrite(LED, led_state);//Update the state of the indicator
}
/*Function: calculate the heart rate*/
void sum()
{
if(data_effect)
{
heart_rate=1200000/(temp[20]-temp[0]);//60*20*1000/20_total_time
Serial.print("Heart_rate_is:\t");
Serial.println(heart_rate);
tempa = analogRead(tempPin);
tempa = tempa * 0.11;
Serial.print("Body Temperature = ");
Serial.print(tempa);
Serial.print("*C");
Serial.println();
delay(1000);
}
data_effect=1;//sign bit
}
/*Function: Interrupt service routine.Get the sigal from the external interrupt*/
void interrupt()
{
temp[counter]=millis();
Serial.println(counter,DEC);
switch(counter)
{
case 0:
sub=temp[counter]-temp[20];
break;
default:
sub=temp[counter]-temp[counter-1];
break;
}
if(sub>max_heartpluse_duty)//set 2 seconds as max heart pluse duty
{
data_effect=0;//sign bit
counter=0;
Serial.println("measurement error,test will restart!" );
arrayInit();
}
else if (counter==20&&data_effect)
{
counter=0;
sum();
}
else if(counter!=20&&data_effect)
{
counter++;
}
else
{
counter=0;
data_effect=1;
}
}
/*Function: Initialization for the array(temp)*/
void arrayInit()
{
for(unsigned char i=0;i < 20;i ++)
{
temp[i]=0;
}
temp[20]=millis();
}

Arduino Loop Error: Waits several seconds to respond to input change

I am trying to write a simple control program for an Arduino Uno for an experiment I'm running at work. Quite simply it just needs to read if an input pin is high, if it is wait 10 milliseconds to turn an output pin high, hold for 10 milliseconds then go low, else the output pin is low.
My problem is that when I run this it ignores the initial delay altogether, and the output pin stays high for several seconds before going low. (using delayMicroseconds)
void setup()
{
pinMode(8, INPUT);
pinMode(13, OUTPUT);
}
void loop()
{
if (digitalRead(8) == HIGH)
{
delayMicroseconds(10000); //wait 10 milliseconds
digitalWrite(13, HIGH); // Pump on
delayMicroseconds(10000); // holds for pulse width of 10 millisecond
digitalWrite(13, LOW); // Pump off
}
else
{
}
}
I've tried setting up something simpler for debugging using the delay function to wait for a second, then turn output pin high, wait for a seconds, then turn output pin low. I did this so I could visually debug using the arduino's built in LED. the result is that it actually continues to run the loop 3 times after the input pin goes low. (using delay)
void setup()
{
pinMode(8, INPUT);
pinMode(13, OUTPUT);
}
void loop()
{
if (digitalRead(8) == HIGH)
{
delay(1000); //wait 1 second
digitalWrite(13, HIGH); // Pump on
delay(1000); // hold for 1 second
digitalWrite(13, LOW); // Pump off
}
else
{
}
}
I can't seem to figure out why it's doing this. I've looked all over and can't seem to find information about why this would happen. I might be missing something really simple, I am not an experienced coder, I just write what I need to run experiments. I've tried reading and writing to the pin register directly using c code, and switching from an if statement to a while loop, none of them fixed the problem. Any insight is greatly appreciated.
You should look at the internal pull-up resistors on the Arduino. You can debounce the signal from your button entirely with software:
void setup() {
pinMode(2, INPUT_PULLUP);
}
void loop() {
if (digitalRead(2) == LOW) // NOTE THAT PULLUPS REVERSE YOUR LOGIC
{
delay(1000); //wait 1 second
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
}
}