Some problems with Arduino prototypes

I am doing a project to control two sensors (ultrasonic and infrared), control them using Arduino. The IR receiver has a filter system inside, so it receives at 36 kHz. I use the srf04 module to process ultrasonic material. If I make a program that needs to control only one sensor, it works. But I have to interpolate two signals into one result. So I used proto-flows! But this does not work ... What kind of mistake?

Here is the code:

#include <pt.h> int iro = 8, iri = 4, us = 12, distanza, us_vcc = 13, ir_vcc = 7; long durata; static struct pt pt1, pt2, pt3; static int irthread(struct pt *pt) { PT_BEGIN(pt); while(1) { PT_WAIT_UNTIL(pt, 1>0); digitalWrite(iro, HIGH); delayMicroseconds(9); digitalWrite(iro, LOW); delayMicroseconds(9); } PT_END(pt); } static int usthread(struct pt *pt) { static unsigned long timer = 0; PT_BEGIN(pt); while(1) { PT_WAIT_UNTIL(pt, millis() - timer > 200); timer = millis(); pinMode(us, OUTPUT); digitalWrite(us, LOW); delayMicroseconds(5); digitalWrite(us, HIGH); delayMicroseconds(10); digitalWrite(us, LOW); pinMode(us, INPUT); durata = pulseIn(us, HIGH); distanza = durata/58; } PT_END(pt); } static int leggithread(struct pt *pt) { static unsigned long timer = 0; PT_BEGIN(pt); while(1) { PT_WAIT_UNTIL(pt, millis() - timer > 200); timer = millis(); Serial.print(distanza); Serial.print("cm "); if (digitalRead(iri) == LOW) Serial.println("ir si"); else Serial.println("ir no"); } PT_END(pt); } void setup() { pinMode(iro, OUTPUT); pinMode(iri, INPUT); pinMode(us_vcc, OUTPUT); digitalWrite(us_vcc, HIGH); pinMode(ir_vcc, OUTPUT); digitalWrite(ir_vcc, HIGH); Serial.begin(9600); PT_INIT(&pt1); PT_INIT(&pt2); PT_INIT(&pt3); } void loop() { irthread(&pt1); usthread(&pt2); leggithread(&pt3); } 

Separate pieces of code for each thread work.


Refresh

I solved my problem (excluded irthread() ), and the code now looks like this:

 #include <pt.h> int iro = 8, iri = 4, us = 12, distanza, us_vcc = 13, ir_vcc = 7; long durata; static struct pt pt1, pt2; static int usthread(struct pt *pt) { static unsigned long timer = 0; PT_BEGIN(pt); while(1) { PT_WAIT_UNTIL(pt, millis() - timer > 200); timer = millis(); pinMode(us, OUTPUT); digitalWrite(us, LOW); delayMicroseconds(5); digitalWrite(us, HIGH); delayMicroseconds(10); digitalWrite(us, LOW); pinMode(us, INPUT); durata = pulseIn(us, HIGH); } PT_END(pt); } static int leggithread(struct pt *pt) { static unsigned long timer = 0; PT_BEGIN(pt); while(1) { PT_WAIT_UNTIL(pt, millis() - timer > 200); timer = millis(); distanza = durata/58; Serial.print(distanza); Serial.print("cm "); if(digitalRead(iri) == LOW) Serial.println("ir si"); else Serial.println("ir no"); } PT_END(pt); } void setup() { pinMode(iro, OUTPUT); tone(iro, 36000); pinMode(iri, INPUT); pinMode(us_vcc, OUTPUT); digitalWrite(us_vcc, HIGH); pinMode(ir_vcc, OUTPUT); digitalWrite(ir_vcc, HIGH); Serial.begin(9600); PT_INIT(&pt1); PT_INIT(&pt2); } void loop() { usthread(&pt1); leggithread(&pt2); } 

Now the problem is in the ultrasonic sensor. If I manage it in one program without protoflows, it can reach objects at a distance of up to 3 meters. Now, even if I put something on 1 meter, the "distance" is a maximum of 15 cm. What is the mistake?

+7
source share
4 answers

In irthread() second argument to the PT_WAIT_UNTIL macro PT_WAIT_UNTIL always evaluated as true:

 PT_WAIT_UNTIL(pt, 1>0); 

Thus, the program will get stuck in an infinite irthread () loop, because part of the result of the macro PT_WAIT_UNTIL in this case looks like if(!(1>0)) return 0; ; the return 0 never called.


It works for usthread() and leggithread() as the second argument is false for the first 200 milliseconds, and the variables are set, so it will again be false another 200 milliseconds after true for once .

For some background information, see How prototypes really work .

+6
source

The timers in leggithread() and usthread() interfere with each other. They use the same timer variable. When the time increases, after about 200 milliseconds from the last time, in, say leggithread() , the variable reset. This means that the condition in another function, usthread() (which is called immediately after), will be false, although the condition there should have been true. Thus, at least another 200 milliseconds will usthread() can do the job (giving a pulse of 10 microseconds to port 12).

There is no guarantee that both functions will be called. If you are out of luck, only one of them can be called if it is a deterministic system (controlled from the same clock, a microcontroller chip).

It may be random which one is called up or there may be some kind of smoothing between several frequencies (for example, one frequency, represented by the number of executed commands for each cycle - this frequency will change when the program changes).

If you want both leggithread() and usthread() do work five times per second, each of them must have an independent timer, using separate variables, for example timer1 and timer2 .

0
source

Why did you put while(1) in your function? Since 1 is always true -

  while(1) { // The code in it will repeat forever } // And the Arduino will never get here 

Either you put logic in place of 1 (for example, while(x > 10) , while(task_finished) ), or do not put your code in a while statement.


  static int usthread(struct pt *pt) { static unsigned long timer = 0; PT_BEGIN(pt); while(1) { // <<<<<<<<< Fault 1 PT_WAIT_UNTIL(pt, millis() - timer > 200); 

  PT_BEGIN(pt); while(1) { //<<<<<<<<< Fault 2 PT_WAIT_UNTIL(pt, millis() - timer > 200); timer = millis(); 
0
source

I came across this and although in an old post I thought that I should comment on the use of the local variable timer, since anyone reading this might get confused. Variables called timer are static local variables used in two functions, and since they are local, their scope is limited by the function in which they are used. This means that the name they have will not act outside of these functions and cannot but influence each other. -they are two different variables on the heap (and not on the stack, because they are defined as static) - they just have the same name inside these functions, but compile to different addresses.

0
source

Source: https://habr.com/ru/post/889727/


All Articles