What does the wait() function do? - c++

Hi I started learning Java and am currently trying to learn C++. I have this piece of code and cannot workout what it does. I am assuming it makes the program wait for a certain period of time before it starts. But some further explanation would very useful.
I have added comments to sections for which I would like some further explanation.
for (;;) {
wait (0.02); //What does this do?
if (ab1_On) {
con += 104;
ab1_On = 0; //Why is the value reset to 0?
}
if (ab2_On) {
con += 208;
ab2_On = 0; //Why is the value reset to 0?
}
con++;
if (con > 311) {
con -= 312;
}
for (int i=0; i<3; i++) {
bright[i] = brilvl (con + (i * 104));
}
}
}

wait() is a function defined in the mbed SDK.
https://developer.mbed.org/handbook/Wait
In your program wait(0.02) will block execution for 20 milliseconds.
for (;;) is an infinite loop, it will run forever. The wait() may be being used to prevent the effects of switch bounce if ab1_on and ab2_on are being set by some mechanical switch.

Related

Arduino serial monitor lagging and cant get it to work

I wrote this program to check some things m but for me it is not working
` #define outputA 7
#define outputB 3
int counter = 0;
int aState;
int aLastState;
int StateAreTheSamePrinted = 0;
int StatePrinted = 0;
void setup() {
// put your setup code here, to run once:
pinMode(outputA, INPUT);
pinMode(3, INPUT);
Serial.begin(115200);
aLastState = digitalRead(outputA);
Serial.print("Arduino started");
}
void loop() {
// put your main code here, to run repeatedly:
aState = digitalRead(outputA);
if(StatePrinted == 0)
{
Serial.print(aState);
StatePrinted = 1;
}
if(aState == aLastState && StateAreTheSamePrinted == 0)
{
Serial.print("States are the same");
StateAreTheSamePrinted = 1;
}
if(aState != aLastState)
{
if(aState == 1){
Serial.print("A is high \n");
}
else
{
Serial.print("A is low \n");
}
StateAreTheSamePrinted = 0;
StatePrinted = 0;
}
aLastState = aState;
}
It always prints once arduino started, 1 (state of input), and states are the same, when I wire 5v from arduino into port 7, sometimes it react once, sometimes n ot, after few minutes it start priting output like 50-100 lines of messages and stops and lags again. Does anyone got into this problem?
`
I was expecting that after giving power into arduino 7 port it would print A is high or A is low and toggle between them
Sounds like you need to "debounce" after the state changes. When you hook 5v into the pin, it might not make a stable connection right away so it changes state very quickly a few times. A simple fix is to put a ~10ms delay after it detects a state change.

How to allocate a period of time for a thread to execute?

I have a class executing in a thread.
But I only want to allow it to run for 10 seconds.
Note... I have no means of passing any boolean into the class to stop execution.
So, How can I set up a thread to terminate after 10 seconds?
The class I am testing has potential infinite recursion that may take place and it is pointless to let it run longer than 10 seconds.
TEST_METHOD(TM_ClientServer_Threads)
{
bool bDone = false;
int ii = 0;
std::thread tCounter([&bDone, &ii]()
{
// Black Box: can't touch this; can't pass in a Boolean
while(true)
{
ii++;
}
}
);
std::thread tTimer([&bDone, &tCounter]()
{
Sleep(1000);
bDone = true;
// kill the tCounter thread ?
}
);
tCounter.join();
tTimer.join();
ii = ii + 0; // break point here
}

detached std::thread on esp32 arduino sometimes blocks, sometimes doesn't

I have some code running on ESP32 microcontroller with arduino core,
In the setup() function I wish to have some code threadPressureCalib run independently in its own thread, so I do the following:
std::unique_ptr<std::thread> sensorCalib;
void setup()
{
sensorCalib.reset(new std::thread(threadPressureCalib));
std::thread* pc = sensorCalib.get();
pc->detach();
}
void loop()
{
...
}
Then, I define threadPressureCalib() as follows:
void threadPressureCalib()
{
float pressure=0;
int count;
for(timestarted = millis();(millis()-timestarted) < 10000;)
{ // THIS ONE BLOCKS SETUP() AND LOOP() CODE EXECUTION
Serial.println("Doing things");
}
Serial.println("Doing other things");
for (count=1; count<= 5;count++)
{ //THIS ONE DOES NOT BLOCK SETUP() and LOOP()
float temp;
while(!timer2.Delay(2000)); //Not sure if this is blocking anything
do{
temp = adc_pressure();
}while(temp>104.0 || temp<70.0); //Catch errors
pressure += temp;
}
changeSetting(pressure/5.0);
return;
}
Problem: During the first for loop, the setup() function's execution is stopped (as well as loop())
During the second for loop, nothing is stopped and the rest of the code runs in parallel (as expected)
Why is it that the first half of this code blocks, and then the second half does not?
Sorry if the question is vague or improperly asked, my first q here.
Explanation of timer2 per request in comments:
timer2 is a custom timer class, timer2.Delay(TIMEOUT) stores timestamp the first time it's called and returns false on every subsequent call until the current time = TIMEOUT, then it returns true and resets itself
NonBlockDelay timer2;
//time delay function (time in seconds to delay)
// Set iTimeout to current millis plus milliseconds to wait for
/**
* Called with milliseconds to delay.
* Return true if timer expired
*
*/
//Borrowed from someone on StackOverflow...
bool NonBlockDelay::Delay (unsigned long t)
{
if(TimingActive)
{
if((millis() >iTimeout)){
TimingActive = 0;
return(1);
}
return(0);
}
iTimeout = millis() + t;
TimingActive = 1;
return(0);
};
// returns true if timer expired
bool NonBlockDelay::Timeout (void)
{
if(TimingActive){
if((millis() >iTimeout)){
TimingActive = 0;
iTimeout = 0;
return(1);
}
}
return(false);
}
// Returns the current timeout value in milliseconds
unsigned long NonBlockDelay::Time(void)
{
return iTimeout;
}
There is not enough information here to tell you the answer but it seems that you have no idea what you are doing.
std::unique_ptr<std::thread> sensorCalib;
void setup(){
sensorCalib.reset(new std::thread(threadPressureCalib));
std::thread* pc = sensorCalib.get();
pc->detach();
}
So here you store a new thread that executes threadPressureCalib then immediately detach it. Once the thread is detached the instance std::thread no longer manages it. So what's the point of even having std::unique_ptr<std::thread> sensorCalib; in the first place if it literally does nothing? Do you realize that normally you need to join the thread if you wish to wait till it's completion? Could it be that you just start a bunch of instances of these threadPressureCalib - as you probably don't verify that they finished execution - and they interfere with each other?

Qt timers cannot be stopped from another thread

Hy,
I'm writing my first Qt program and getting now in troubles with:
QObject::killTimer: timers cannot be stopped from another thread
QObject::startTimer: timers cannot be started from another thread
My program will communicate to a CANOpen bus for that I'm using the Canfestival Stack. The Canfestival will work with callback methods. To detects timeout in communication I setup a timer function (somehow like a watchdog). My timer package consist out of a "tmr" module, a "TimerForFWUpgrade" module and a "SingleTimer" module. The "tmr" module was originally C programmed so the static "TimerForFWUpgrade" methods will interface it. The "tmr" module will be part of a C programed Firmware update package.
The timer will work as follows. Before a message is sent I will call TMR_Set method. An then in my idle program loop with TMR_IsElapsed we check for a timer underflow. If TMR_IsElapsed I will do the errorhandling. As you see the TMR_Set method will be called continuously and restart the QTimer again and again.
The above noted errors are appearing if I start my program. Can you tell me if my concept could work? Why does this errors appear? Do I have to use additional threads (QThread) to the main thread?
Thank you
Matt
Run and Idle loop:
void run
{
// start communicate with callbacks where TMR_Set is set continously
...
while(TMR_IsElapsed(TMR_NBR_CFU) != 1);
// if TMR_IsElapsed check for errorhandling
....
}
Module tmr (interface to C program):
extern "C"
{
void TMR_Set(UINT8 tmrnbr, UINT32 time)
{
TimerForFWUpgrade::set(tmrnbr, time);
}
INT8 TMR_IsElapsed(UINT8 tmrnbr)
{
return TimerForFWUpgrade::isElapsed(tmrnbr);
}
}
Module TimerForFWUpgrade:
SingleTimer* TimerForFWUpgrade::singleTimer[NR_OF_TIMERS];
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent)
{
for(unsigned char i = 0; i < NR_OF_TIMERS; i++)
{
singleTimer[i] = new SingleTimer(parent);
}
}
//static
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
time *= TimerForFWUpgrade::timeBase;
singleTimer[tmrnbr]->set(time);
}
}
//static
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
if(true == singleTimer[tmrnbr]->isElapsed())
{
return 1;
}
else
{
return 0;
}
}
Module SingleTimer:
SingleTimer::SingleTimer(QObject* parent) : QObject(parent),
pTime(new QTimer(this)),
myElapsed(true)
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_setElapsed()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->setSingleShot(true);
}
void SingleTimer::set(unsigned int time)
{
myElapsed = false;
pTime->start(time);
}
bool SingleTimer::isElapsed()
{
QCoreApplication::processEvents();
return myElapsed;
}
void SingleTimer::slot_setElapsed()
{
myElapsed = true;
}
Use QTimer for this purpose and make use of SIGNALS and SLOT for the purpose of starting and stopping the timer/s from different threads. You can emit the signal from any thread and catch it in the thread which created the timer to act on it.
Since you say you are new to Qt, I suggest you go through some tutorials before proceeding so that you will know what Qt has to offer and don't end up trying to reinvent the wheel. :)
VoidRealms is a good starting point.
You have this problem because the timers in the static array is created in Thread X, but started and stopped in Thread Y. This is not allowed, because Qt rely on thread affinity to timeout timers.
You can either create, start stop in the same thread or use signal and slots to trigger start and stop operations for timers. The signal and slot solution is a bit problematic Because you have n QTimer objects (Hint: how do you start the timer at position i?)
What you can do instead is create and initialize the timer at position tmrnbr in
TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
singleTimer[tmrnbr] = new SingleTimer(0);
singleTimer[tmrnbr]->set(time);
}
which is executed by the same thread.
Futhermore, you don't need a SingleTimer class. You are using Qt5, and you already have all you need at your disposal:
SingleTimer::isElapsed is really QTimer::remainingTime() == 0;
SingleTimer::set is really QTimer::setSingleShot(true); QTimer::start(time);
SingleTimer::slot_setElapsed becomes useless
ThusSingleTimer::SingleTimer becomes useless and you dont need a SingleTimer class anymore
I got the errors away after changing my timer concept. I'dont use anymore my SingleTimer module. Before the QTimer I won't let timeout and maybe because of that I run into problems. Now I have a cyclic QTimer that times out every 100ms in slot function I will then count the events. Below my working code:
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent) : QObject(parent),
pTime(new QTimer(this))
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_handleTimer()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->start(100);
}
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
if(timeBase != 0)
{
myTimeout[tmrnbr] = time / timeBase;
}
else
{
myTimeout[tmrnbr] = 0;
}
myTimer[tmrnbr] = 0;
myElapsed[tmrnbr] = false;
myActive[tmrnbr] = true;
}
}
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
QCoreApplication::processEvents();
if(tmrnbr < NR_OF_TIMERS)
{
if(true == myElapsed[tmrnbr])
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0; // NOK
}
}
void TimerForFWUpgrade::slot_handleTimer()
{
for(UINT8 i = 0; i < NR_OF_TIMERS; i++)
{
if(myActive[i] == true)
{
myTimer[i]++;
if(myTimeout[i] < myTimer[i])
{
myTimer[i] = 0;
myElapsed[i] = true;
myActive[i] = false;
}
}
}
}

Why is my PIC not blinking its leds?

I am trying to get started with pic24's, specifically the PIC24FJ64GA002, and I have looked in the datasheet at the registers and whatnot, but I still cannot get it to blink the leds. When I run it via debug it runs correctly, but when I try to actually run it on the pic it seems to not run at all.
I am using an external Oscillator, a 8MHZ Oscillator specifically, connected to pins 9(OSCI) and 10 (OSCO). Compiler is C30 in Mplab.
Datasheet link is: http://ww1.microchip.com/downloads/en/DeviceDoc/39881D.pdf
The code is below
//include basic header definition
#include <p24FJ64GA002.h>
//config
_CONFIG2(0x0200);
_CONFIG1(0x0800);
int i;
//main loop
int main(void)
{
OSCCON = 0x2280; //select external OSC, no PLL
AD1PCFG = 0xFFFF; //set to all digital I/O
TRISA = 0x0000; //configure all PortA as output
while(1) //Loop forever
{
LATAbits.LATA0 = 1; //RA0 = 1
Wait();
LATAbits.LATA0 = 1; //RA0 = 1
Wait();
}
}
int Wait(void) // gives me a nice delay of 1/3rd a second or so
{
for (int i = 0; i < 30000; i++)
{
for (int i = 0; i < 30; i++);
}
}
You need to go hi, wait, then lo, wait... you are just going hi, wait, hi, wait.
while(1) //Loop forever
{
LATAbits.LATA0 = 1; //RA0 = 1
Wait();
LATAbits.LATA0 = 0; //RA0 = 1
Wait();
}
What optimization level are you compiling with? If it's only working in debug, it's possible the optimizer is reducing the whole Wait() function to a no-op. Try declaring `volatile int i'.
Thank you guys for all your help, but it was that I set the config bits wrong, when I set them in the config editor in mplab all works well.
Thank you for all your help!