I have an Arduino MEGA 2560 running a FreeRTOS sketch using Arduino_FreeRtos. Everything appears to be working correctly except for vTaskDelay functions. Below is one of the areas I am having an issue.
taskENTER_CRITICAL();
MOTORS[5].motor(1, 120);
MOTORS[6].motor(1, 127);
taskEXIT_CRITICAL();
vTaskDelay(pdMS_TO_TICKS(9000));
taskENTER_CRITICAL();
MOTORS[5].motor(1, 0);
MOTORS[6].motor(1, 0);
taskEXIT_CRITICAL();
The first task critical section starts moving my motor forward. There is supposed to be a 9 second delay and then the motor is supposed to stop in the second task critical section. What is actually happening is the motor moves forward for ~1 second and then stops.
I do have INCLUDE_vTaskDelay enabled in the FreeRTOSConfig.h file.
What else can I look at to try and find out why vTaskDelay is not working?
Below is the definition for the clock. Per comment that the clock may not be correct. I can't decipher if the clock is correct or not. Hopefully someone can point out if this setting may be causing the issue.
The I think the problem is that 128000 >> (portUSE_WDTO + 11) is probably 0 (unless portUSE_WDTO is negative).
In order to get the correct timings you need to check that the tick rate is as expected (30ms). This is unlikely to be the case at the moment.
Related
I have a board with an XMC1400 MCU on it. It is a custom board with LEDs and buttons and so on.
So I accidentally add a '''XMC_SCU_RESET_AssertMasterReset()''' line at the beginning of the code... This function cause xmc to reset but it doesn't just reset the program counter, it also clears everything and ends the debug connection. And since it happens so quickly I cannot reconnect before it resets again. For the one who doesn't know, when you load a program to the xmc, it gets written to the flash, and once it's loaded it will always run with power up.
I know in some boards there are some pins used to clear to board when shorted but there is no such a thing in this one.
There are however several bootstrap loaders(can and uart). But they are disabled by a flash parameter called BMI. I don't have much hope but is there a way to rescue this processor?
Thanks!
I am trying to make a bot that follows a line with IR sensors and I also have a IR sensor to prevent collisions. In the if statement that stops movement, I also have it play a tone, but the problem is the tone doesn't play. I know that the if statement is being executed as the servos do stop as intended and resume after the object is removed. Also the speaker setup is confirmed working as other code with tones are working fine. I did hear it beep a few times when I was troubleshooting which is strange.
Here is the statement with the issue;
if (irDetect == 0) // Object detected
{
servoLeft.writeMicroseconds(1500); // Stop left servo
servoRight.writeMicroseconds(1500); // Stop right servo
tone(5, 4000, 100);
delay(100);
}
I cannot figure out the problem so any help is appreciated.
Tone and the ir library you are using are both using timer2. So you have a timer conflict. Both can't simultaneously have control over timer2. You'll either need to find a new library for one function or the other or modify one to use a different timer.
I am working on a project that requires me to use 2 separate Arduinos running independently from each other. Now, both of these Arduino's are running the same code, but I noticed that after 10 minutes or so, one of them falls behind and this time difference keep increasing with time. Like I already mentioned, the Arduino`s are identical and I bought them at the same time and they are running the same copy of the program. Any ideas what might cause this and how can I fix it?
Thank you.
Here is the link to the Arduino that I bought just in case.
My Arduino modules on Amazon
The Crystal Oszillators have tolerances up to 100ppm (extreme case), which means you could possibly get 16Mhz*100ppm = 1600 clock pulses difference per second. Also the differences of the runtime could be caused by small voltage differences. Even if there is a voltage Regulator on the Board it has small tolerances, based on the fact, that it operates in the Range of MHz this can climb up to an recognizable Offset.
A possible solution is a synchronization of both microcontrollers. I'm not an expert, so the following solution is a possible and easy one, but definitly not the best.
If they are near by each other you can use two pins of each controller. One as Input and one as Output. Write something like this in your code (same for both if you use the same Pins):
digitalWrite(outPin, LOW);
while(digitalRead(inPin)){};
digitalWrite(outPin, HIGH);
Connect the Output from the first to the Input from the second and the same from second to first.
This results in a waiting state for each cycle of the faster Controller until the slower one reaches the same Programm Part. But be careful if one of them stucks somewhere it will stop the second one too. So there is no redundancy! if this was your goal, don't use this method and search for other synchronisation methods.
Perhaps you can use some RTC (real time clock) hardware to help you to keep they synchronised. They are really cheap and easy to use.
I'm building a small robot that uses a relay to power the motors. To run the relay, I have it connected to pins 11 and 12. If I use something like the Blink example, where it turns the pin on, then off a second later, it works fine. However, what I'm trying to do is keep a pin on until an IF statement is met. When I run it, it turns the pin on for a millisecond or so, then off permanently. How could I get this to work?
Well, I have a couple guesses, but your description is vague without knowing what the IF statement is...maybe it is being met somehow without your knowledge.
I am pretty certain the light is staying on longer than a millisecond in order for you to see it. As a side note, here is an interesting, related article: http://www.100fps.com/how_many_frames_can_humans_see.htm
Are you debouncing? http://arduino.cc/en/Tutorial/Debounce
I can imagine a simple program with an IF to count button presses -- or the timing of -- where, without debouncing, you will meet the conditional without it seeming correct.
This is just one possibility, but without knowing the code, or the setup it's hard to say.
I have an Arduino Mega connected to a 6 axis robotic arm. All 6 interrupts are attached to encoders (one encoder pin on an interrupt, the other on a vanilla digital input). The interrupts are handled with this code:
void readEncoder1(){
//encoders is a 2d array, where the first d is the axis, and the two pin numbers
//first pin is on an interrupt (CHANGE), and second is a standard digital in
if (digitalRead(encoders[0][0]) == digitalRead(encoders[0][1])) {
positions[0]++;
} else {
positions[0]--;
}
if(servoEnable){
updatePositions(); //// compares positions[] to targets[] and adjusts motor speed accordingly
}
}
This is designed to keep the arm locked at a certain position- if the arduino detects that the position of the motor is off by a certain threshold, it updates the power going to the motor to keep the arm in position.
The problem is this, then -- if two or three (or more) axis are under load (requiring constant updating to stay in position) or they are moving, the Arduino will stop receiving intact commands on Serial input, several characters will be dropped. The interrupts are obviously running quite quickly, and for some reason this is causing commands to become corrupted. Is there any way around this? Architecturally, am I doing this right? My main instinct is to call updatePositions() in the main run loop at, say, 100 ms intervals, will this significantly reduce interrupt overhead? I guess what my question boils down to is how do I get reliable serial commands into the Arduino even if all 6 encoders are pulsing away?
Quadrature encoders were designed to be read by hardware counters. Pulse rates are generally high with the motor running at full speed. One megahertz is not unusual. The higher the number of pulses, the better the servo loop works and the more accurate you can position the motor.
Doing this is in software with a low-power cpu is, well, challenging. It will fall apart when the ISR takes longer than the interval between pulses. You'll lose pulses and thus position. Especially bad because there is no way you can detect this error condition. And that this loss happens when the robot is moving fast, the worst case condition to lose control.
You absolutely cannot afford to update the servo loop in the interrupt handler so get rid of that first. Keep the ISR to the bare minimum, only count the position and nothing else. The servo loop should be separate, driven by a timer interrupt or tick. You cannot properly control a robot with a 100 msec servo update unless it is big an sluggish, this needs to be a handful of milliseconds at most to get smooth acceleration and stable feedback.
There's a limited amount of wisdom in spending forty bucks to control thousands of dollars worth of robot hardware. Not being able to keep up in the servo loop is something you can detect, shut it down when the position error builds up too much. There's nothing you can do about losing pulses, that's a wreck. Get the hardware counters.
First rule of embedded systems:
Do as little as possible in interrupts.
In your case, just update the positions in the interrupt and run your position/speed control loop in the background or at a lower priority.
Aside: I assume you are aware that you are "losing" encoder pulses as you don't have an interrupt on one of the channels?
Also, interrupt-driven encoder-analysis is very noise-prone. If you get a noise pulse, you'll likely only see an interrupt for one of the edges as they'll be too close together to process both.
A more robust way is to use a state machine which watches all 4 transitions, but that requires either interrupts on both edges of both channels, or polling fast enough to not miss anything up the to rate you are expecting to see.