opencv circle detection with video - c

is there a way to wait until something happens(while loop) or wait wait 10 seconds before doing a circle detection, but still displaying the video. i have tried it with while loop but if condition is not met, frames will not be displayed as code does not get the cvShow\iamge().

Yes, it's possible, but you will have to use threads. Declare a global variable bool exec_circle_detection = false; and start a 2nd thread. On this thread, call sleep(10) to wait for 10 seconds and then change exec_circle_detection to true.
In the main thread, inside the frame grabbing loop, you check if the boolean variable is set to true, and in case it isn't, you won't process the frame. This part would look something like this (in C):
char key = 0;
while (key != 27) // ESC
{
frame = cvQueryFrame(capture);
if (!frame)
{
fprintf( stderr, "!!! cvQueryFrame failed!\n" );
break;
}
if (exec_circle_detection)
{
// execute custom processing
}
// Display processed frame
cvShowImage("result", frame);
// Exit when user press ESC
key = cvWaitKey(10);
}
If you plan to do the circle detection once every 10 seconds, you will need to change exec_circle_detection to false after you execute the custom processing. On the secondary thread, adjust your code so there is a while loop changing exec_circle_detection to true every 10 seconds.

You can simply run the detection every X frames. Add a frame counter in your code, restarting to 0 when detection is perform, increase by one at each grabbed new frame, and perform detection when the counter is equal to 300 considering your video is displayed at 30 fps. You will get your 10 seconds delay between each detections.

Related

is there a way to wait for something without interrupt the execution of other code?

i have to write a function that, by calling it only a single time, have to:
turn on an output pin
the pin stays high for 200mS
at the end of the timer the pin need to be low again.
the pin stays low for 200mS
at the end of the timer the function can be called again.
to turn on and off an output pin I already have wrote and tested the funcions:
outOn(pin_id);
outOff(pin_id);
now, i am trying to write the function that does the above mentioned actions and this is what l've come out with so far:
void outOnT02(enum e_outs ou){
outOn(ou);
gu_RegTim.BTime[BTIM_FUNCT].Timer = O_SEC01*2;
if(gu_RegTim.BTime[BTIM_FUNCT].b.Stato == O_EndTimer) {
outOff(ou);
}
}
the function is named outOnT02 because:
it is an output;
after calling it, the pin became high;
T02 because the pin stays high for 0.2 Seconds.
outOn(ou); makes the pin go high,
outOff(ou); makes the pin go low,
gu_RegTim.BTime[BTIM_FUNCT].Timer = O_SEC01*2;
starts a 200mS timer,
and gu_RegTim.BTime[BTIM_FUNCT].b.Stato == O_EndTimer is true when the timer has run out.
it works but, as you can tell, I have to put it in a cycle otherwise gu_RegTim.BTime[BTIM_FUNCT].b.Stato == O_EndTimer will never be true and so,the pin will stay high forever.
this is where i am stuck. i can't use a SLEEP(200); because i can't interrupt the execution of the code.
the language is C, the ide is MPLAB X IDE v6.00, the compiler is XC8 v2.31 and the cpu is a PIC16F15355.
This post is a little old but it is worth to answer since it is both a good question and a common problem. Now this problem is very common in embedded world when we develop applications that has to run on only one CPU. Hence there is no real parallelism in the workflow. Also since the application will not run on top of any OS, there will be no scheduler, no timers, no threads etc. Especially in small scaled microcontrollers there is no way to run many of the true RTOSs.
But this shouldn't be an obstacle for developing applications that runs tasks concurrently. We can develop an application using some tricks so that it runs the tasks concurrently and behave as a small OS. Running concurrently means that no task blocks the CPU using busy waiting checks or something alike but we block a task that needs to wait some event to occur.
When we block a task, the specific data and the next execution point on that task must be preserved so that it can continue from where it should in the next execution. Knowing what we need to preserve helps us to create a thread-like structures that executes until it has to wait some event to occur (eg. time delay). When it has to wait (means that it will be blocked) the next state of it must be preserved and it exits to give the control to the CPU so that it executes other tasks.
When we need to deal with periodic tasks as in the question, it is relatively easier to implement without blocking the CPU execution and meanwhile handle other tasks. Moreover no interrupt usage needed for this type of tasks unless the tasks are extremely time sensitive.
Well, enough with the story part, let's get into it. I will base the examples on the OP's output flashing problem. However the same techniques can be applied for other situations like I/O events, hardware events etc.
Let's sum up the requirement briefly, we have a task that runs atomically. That is, when it is called it must run to completion so that it can be called again (this is what I understand from the OP's requirement):
Turns on an output pin for 200ms
Then turns off the pin for 200ms
Once turned off and 200ms time has elapsed it can be executed again.
Note Some functions in this example are not implemented since they can be application or microcontroller specific.
Task-like Functions
Let's assume we want to schedule the following two task-like functions each of which keeps track of its execution continuation points.
The static cp variables are declared in each function so that they remember where to continue whenever they are called. The content of cp variable will not be destroyed by the compiler when the function returns since we declare it as static. The cp needs to be updated upon the expected events occur in order to proceed to the next step whenever it is called.
Note that in outputTask, the call source must be known to control its atomic behaviour. Since the requirement for this task is that once it triggered or called, it must run to completion. So we have to know where the task is called from, in order it to decide what to do on each call. If it has been triggered from another task, it can't be triggered anymore until it completes its flashing prosess. If it is called from the scheduler (main loop) it knows it is a periodic call and will keep track of the time. This control is achieved using a parameter called periodic. When it is called from the scheduler this parameter must be set to 1, and 0 for the calls other than the scheduler.
/*
* This task-like function performs what the OP wants to achieve
*/
void outputTask(unsigned char periodic) {
static unsigned char cp = 0; // Continuation Point holder
static unsigned char currentMillis;
/*
* Check whether it is a periodic call or a new output signal call.
* If it is a periodic call and signalling has been initialized,
* proceed for time keeping.
* If it is a new signalling call and the task hasn't completed yet,
* simply ignore and return.
*/
if(!periodic && cp != 0) {
return;
}
switch(cp) {
case 0:
outOn(pin_id); // Turn on the output
cp = 1; // Next execution point
currentMillis = 200; // Load the 200ms counter for time keeping
break;
case 1:
currentMillis--;
if(currentMillis == 0) {
// 200ms time for output high has elapsed, proceed to next step
outOff(pin_id); // Turn off the output
currentMillis = 200; // Reload the counter value
cp = 2; // Proceed to the next step
}
break;
case 2:
currentMillis--;
if(currentMillis == 0) {
// 200ms time for output low has elapsed, proceed to next step
cp = 0; // Last step is done, reset the state for new calls
}
break;
default:
// For anything else, reset the task state to the initials
cp = 0 // Reset the task state to zero so that it accepts new calls
}
}
/*
* Let's say this task will wait for a button press event and will
* trigger the outputTask upon the event occurs
*/
void outputTriggerTask() {
static unsigned char cp = 0;
static unsigned char currentMillis;
switch(cp) {
case 0:
if(isButtonPressed()) { // Platform specific function
// A button press has been detected, debounce first
currentMillis = 50;
cp = 1; // Next step, check for the elapsed time
}
else {
break;
}
case 1:
currentMillis--;
if(currentMillis == 0) {
// Check whether the button press is consistent
if(isButtonPressed()) {
// Yes still consistent, handle the button press by triggering the output task
outputTask(0); // Not a periodic call
cp = 2; // Next step is to check whether button is released
}
else {
cp = 0; // Reset the task state
}
}
break;
case 2:
if(isButtonReleased()) { // Platform specific function
currentMillis = 50; // Reload the time counter
cp = 3;
}
else {
break;
}
case 3:
currentMillis--;
if(currentMillis == 0) {
// Check whether the button release is consistent
if(isButtonReleased()) {
// Yes still consistent, handle the button release if needed
cp = 0; // Reset the task to its initial state
}
}
break;
default:
cp = 0; // Reset to initials
}
}
Scheduling Approches
The following approches are for non RTOS small embedded systems. They are suitable for wide range of 8-bit microcontrollers.
Approach 1 - Create Delay Based Timebase to Schedule Tasks
Scheduling using CPU blocking delay is suitable for hobby and educational purposes while it is not suitable for real projects. This example uses a platform specific delay_ms function (or can be a macro) to create a 1ms heartbeat for the application so that the tasks can keep track of time.
void main(void) {
systemInit(); // Platform specific function
// maybe some more init functions go here
// Application's infinite scheduler loop
while(1) {
// The first thing we do is to create a 1ms timebase using delay.
// This is the heartbeat for the application
delay_ms(1000); // Platform specific function
// 1ms has elapsed check the tasks
outputTriggerTask(); // Check whether any button press event has occured
outputTask(1); // It is a periodic call for the output task
// Maybe more tasks go here...
}
}
Approach 2 - Create Hardware Timer Based Timebase
void main(void) {
systemInit(); // Platform specific function
// Setup a hardware timer for 1ms overflow without interrupt
initTimerForOneMs(); // Platform specific function
// maybe some more init functions go here
// Application's infinite scheduler loop
while(1) {
// Wait for the timer to overflow
while(!isTimerOverflow()) // Platform specific function
;
// Timer has overflowed, reload and check tasks
reloadTimer(); // Platform specific function
// 1ms has elapsed check the tasks
outputTriggerTask(); // Check whether any button press event has occured
outputTask(1); // It is a periodic call for the output task
// Maybe more tasks go here...
}
}
Approach 3 Put the Processor to Sleep for 1ms Timebase
void main(void) {
systemInit(); // Platform specific function
// maybe some more init functions go here
// Application's infinite scheduler loop
while(1) {
// Put the Processor to sleep along with a watchdog timer to wake it up
clearWatchdogTimer(); // Platform specific function
sleep(); // Platform specific function
// CPU slept for 1ms and woke up, handle the periodic tasks
outputTriggerTask(); // Check whether any button press event has occured
clearWatchdogTimer(); // Platform specific function
outputTask(1); // It is a periodic call for the output task
clearWatchdogTimer(); // Platform specific function
// Maybe more tasks go here...
}
}
And Last But not Least Time Checking Approach
In this approach the tasks will be keeping the time by checking better say comparing the elapsed time to the desired time to delay tasks without blocking the CPU. For this, we will need to use a free running timer. This will be like the millis function of the Arduino API.
Rewriting the Tasks for the Time Checking Approach
/*
* This task-like function performs what the OP wants to achieve
*/
void outputTask(unsigned char periodic) {
static unsigned char cp = 0; // Continuation Point holder
static unsigned short currentMillis; // 16 bit millisecond holder
/*
* Check whether it is a periodic call or a new output signal call.
* If it is a periodic call and signalling has been initialized,
* proceed for time keeping.
* If it is a new signalling call and the task hasn't completed yet,
* simply ignore and return.
*/
if(!periodic && cp != 0) {
return;
}
switch(cp) {
case 0:
outOn(pin_id); // Turn on the output
cp = 1; // Next execution point
currentMillis = getCurrentMillis(); // Platform specific function
break;
case 1:
if(getCurrentMillis() - currentMillis >= 200) {
// 200ms time for output high has elapsed, proceed to next step
outOff(pin_id); // Turn off the output
currentMillis = getCurrentMillis(); // Reload the counter value
cp = 2; // Proceed to the next step
}
break;
case 2:
if(getCurrentMillis() - currentMillis >= 200) {
// 200ms time for output low has elapsed, proceed to next step
cp = 0; // Last step is done, reset the state for new calls
}
break;
default:
// For anything else, reset the task state to the initials
cp = 0 // Reset the task state to zero so that it accepts new calls
}
}
/*
* Let's say this task will wait for a button press event and will
* trigger the outputTask upon the event occurs
*/
void outputTriggerTask() {
static unsigned char cp = 0;
static unsigned short currentMillis;
switch(cp) {
case 0:
if(isButtonPressed()) { // Platform specific function
// A button press has been detected, debounce first
currentMillis = getCurrentMillis(); // Platform specific function
cp = 1; // Next step, check for the elapsed time
}
else {
break;
}
case 1:
if(getCurrentMillis() - currentMillis >= 50) {
// Check whether the button press is consistent
if(isButtonPressed()) {
// Yes still consistent, handle the button press by triggering the output task
outputTask(0); // Not a periodic call
cp = 2; // Next step is to check whether button is released
}
else {
cp = 0; // Reset the task state
}
}
break;
case 2:
if(isButtonReleased()) { // Platform specific function
currentMillis = getCurrentMillis();
cp = 3;
}
else {
break;
}
case 3:
if(getCurrentMillis() - currentMillis >= 50) {
// Check whether the button release is consistent
if(isButtonReleased()) {
// Yes still consistent, handle the button release if needed
cp = 0; // Reset the task to its initial state
}
}
break;
default:
cp = 0; // Reset to initials
}
}
Scheduler for Time Checking Approach
void main(void) {
systemInit(); // Platform specific function
initMillisTimerWithInterrupt(); // Platform specific function
// maybe some more init functions go here
// Application's infinite scheduler loop
while(1) {
// Now that we use a free running millis timer no need to block the CPU to create a timebase
// Just call tasks sequentially. Each task will know what to do individually
outputTriggerTask(); // Check whether any button press event has occured
outputTask(1); // It is a periodic call for the output task
// Maybe more tasks go here...
}
}

Improvements in led indication with RTOS code

I want to make certain effects with RGB led which changes colour using PWM signals.
|¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯|
| Green || Yellow || Pink |
|__________||__________||__________|
15ms 10ms 25ms
|¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯|
| Blue || Magneta || Blue |
|__________||__________||__________|
20ms 10ms 20ms
Based on interrupt, these led colours should be displayed on LED.
I made a task specifically for this purpose and running these effects on that task.
while(1)
{
if (indication_type == event_a)
{
led_color_green();
osDelay(15);
led_color_yellow();
osDelay(10);
led_color_pink();
osDelay(25);
}
else if (indication_type == event_b)
{
led_color_blue();
osDelay(20);
led_color_magneta();
osDelay(10);
led_color_blue();
osDelay(20);
}
else
..
..
}
Code is working but there are two issues
Each led effect is visible for 50ms and if an event change has occurred, the led keeps on executing the previous state and a new state is showed after it has exited if-else condition with delay as per current implementation. How can I change the led indication immediately after receiving an interrupt?
I think there should be some clean way to make such effects especially with led. How can I improve this code? Any code reference you can share?
I am using STM32F4 and CMSIS RTOS v2
You need to be able to make a decision about the "indication type" at every time quanta (tick), and switch the sequence immediately.
The following is an outline of one way to do that:
// Color/time descriptor for each sequence
static const struct
{
void (*setcolor)(void) // Pointer to color set function
int showtime ; // Time to display color
} indication_descriptor[][3] =
{
{ {led_color_green, 15}, {led_color_green, 15}, {led_color_green, 15} }, // event_a sequence
{ {led_color_blue, 15}, {led_color_magneta, 15}, {led_color_blue, 15} }, // event_b sequence
...
} ;
// Sequence control variables
int last_indication_type = indication_type - 1 ; // force "change" on first iteration
int current_indication = 0 ;
int current_step = 0 ;
int step_time = 0 ;
while(1)
{
// On indication change...
if( indication_type != last_indication_type )
{
// Set the indication descriptor...
if( indication_type == event_a )
{
current_indication = 0 ;
}
else if( indication_type == event_b )
{
current_indication = 1 ;
}
...
last_indication_type = indication_type ;
// Set initial indication color and time for this sequence
current_step = 0
step_time = indication_descriptor[current_indication][0].showtime ;
indication_descriptor[current_indication][0].setcolor() ;
}
// Wait one tick
osDelay(1) ;
// Decrement time in step
step_time-- ;
// If end of step...
if( step_time == 0 )
{
// Set colour and time for next step
current_step == (current_step % 3) ;
step_time = indication_descriptor[current_indication][current_step].showtime ;
indication_descriptor[current_indication][current_step].setcolor() ;
}
}
It is likely that further improvements can be made, but from the fragment you have provided it is not possible to advise. For example the data type and range of indication_type, event_a etc are not shown - it is possible that a switch-case or lookup table or even arithmetic could replace the if/else if/.../else selection block, but more information would be required.
If you need faster and more deterministic sequence interruption than 1ms you'd have to use an osTimer, with a callback function that sets a thread flag and have the task wait on a thread flag rather than osDelay(). The interrupter can then set a different thread flag to wake the task to abort the timer and switch indication. That is somewhat more complex however and likely not necessary in this case. A pattern that is useful for when hard-real-time response at the microsecond order is required. If you did that the sequence code might change thus:
...
// Set initial indication color and time for this sequence
current_step = 0
osTimerStart( step_timer, indication_descriptor[current_indication][0].showtime ) ;
indication_descriptor[current_indication][0].setcolor() ;
}
// Wait for timer expiry or event
uint32_t flags = osThreadFlagsWait( STEP_COMPLETE_FLAG | SEQUENCE_CHANGE_FLAG, osFlagsWaitAny, step_time ) ;
// If end of step...
if( (flag & STEP_COMPLETE_FLAG) != 0 )
{
// Set colour and time for next step
current_step == (current_step % 3) ;
step_time = indication_descriptor[current_indication][current_step ].showtime ;
indication_descriptor[current_indication][current_step].setcolor() ;
}
else
{
osTimerStop( step_timer ) ;
}
It has the advantage of having far fewer task context switches which may be useful if you need to reduce CPU load to achieve real-time deadlines or reduce power consumption by entering sleep for longer periods.
osWait allows you to wait for either an event or a timeout. So if you can generate a proper signal when you have an interrupt, the thread will wake-up and you can immediately switch LED state.
See https://www.keil.com/pack/doc/cmsis/RTOS/html/group__CMSIS__RTOS__Wait.html#details
Put the RTOS to work and use an RTOS timer. From the interrupt that triggers the change in indication_type, you can call your function to set the color and then start the timer for the desired color duration (this can also be done in a task context after the interrupt notifies the task). On the timeout, set the next color and restart the timer with the next color duration. When indication_type changes, you can simply set the color again and restart the timer with the new indication_type color pattern.

Fixed time for executing a task on the KEIL RTX RTOS

I am using KEIL RTX RTOS which used pre-emptive round robin scheduler.I have a LCD for displaying data and a few tasks have access to this LCD(there are some other tasks also),These tasks need fixed time for handling the LCD(e.g. first task handle LCD for displaying it's data for 50 seconds and after 50 seconds,second task handle and displays it's data for 10 seconds). I know i must use mutex for managing accessing to LCD.but i dont know how i must manage its for fixed times?LCD tasks are in the lowest priority and if there are not any other task to execution these tasks will be execute for displaying messages.
I'll try to answer your question first but then I'm going to propose an alternate design for you to consider.
You should use a Timer in order to base anything in real-world time, especially a period that is relatively long, like these which are measured in seconds. Create two Timer objects, one with a 50 second period and one with a 10 second period. Both timers should be one-shot type. Also create two Signal objects, one to indicate that the 50 second period has expired and another to indicate that the 10 second period has expired. The two Timer objects each call distinct callback functions when they expire. The 50 second callback function should set the 50 second expiration Signal and then start the 10 second Timer. The 10 second callback function should set the 10 second expiration Signal and then restart the 50 second Timer. The timers will ping-pong back and forth, alternately setting the two signals.
Now your resource using tasks should periodically check for the appropriate expiration Signal. When the task observes that the Signal is set it can give up the resource and clear the Signal. The other task does the same thing with the other Signal. This way the two tasks know when to give up the resource and allow the other task to obtain it.
One thing that bothers me about your design is that you have two synchronization mechanisms protecting your resource. A mutex is a synchronization mechanism. When tasks are tying to use a resource asynchronously (i.e., at random times), a mutex can be used to synchronize those usages and ensure only one task is using the resource at any given time. If you already have another synchronization mechanism then you probably don't need the mutex. In other words, If your tasks have distinct time slots in which they use the resource then they're already synchronous. If they're not going to attempt to use the resource at random times then you may not need a mutex.
Your design also seems complicated and I wonder whether this alternate design might be simpler.
Consider making a single task that is responsible for the LCD display interface. This LDC task is the only task that will interface with the display. Your data tasks will send messages to the LCD task when they produce data to be displayed. The LCD task will simply wait for these messages and display the data appropriately when they arrive. You could use either a Message Queue or a Mail Queue for this message service depending upon how complicated and varied the data is. Now you don't need a mutex for the LCD display because there is only one task that uses it. And do you still need the 50/10 second time split with this design? I'm not sure because I don't know what was the source of that requirement.
Rather then have multiple threads accessing a single resource arbitrated by mutexes, it would be simpler to have a single thread handle the resource.
In this case I suggest a display manager thread, the other threads can register with the display manger providing perhaps a pointer to a display buffer, and the required display period. The display manager then simply cycles through each registered thread displaying its buffer for the required period before switching to the next.
For example (pseudo-code):
static struct
{
const char* frame_buffer ;
int display_seconds ;
OS_MUTEX mutex ;
} display_registry[MAX_DISPLAY_THREADS] = {0,0} ;
void displayLock( int handle )
{
if( handle >= 0 && handle < MAX_DISPLAY_THREADS )
{
os_mutex_lock( display_registry[handle].mutex ) ;
}
}
void displayUnock( int handle )
{
if( handle >= 0 && handle < MAX_DISPLAY_THREADS )
{
os_mutex_unlock( display_registry[handle].mutex ) ;
}
}
void lcd_thread
{
int display = 0 ;
for(;;)
{
int t = 0 ;
while( t < display_registry[display].display_seconds &&
display_registry[display].frame_buffer != 0 )
{
displayLock( display ) ;
render_display( display_registry[display].frame_buffer ) ;
displayUnlock( display ) ;
delay( ONE_SECOND ) ;
}
display = (display + 1) % MAX_DISPLAY_THREADS ;
}
}
int displayRegister( const char* frame_buffer, int display_seconds )
{
for( int i = MAX_DISPLAY_THREADS - 1;
frame_buffer[i] != 0 &&
i >= 0; i-- )
{
// do nothing
}
if( i >= 0 )
{
display_registry[i].display_seconds = display_seconds ;
display_registry[i].frame_buffer = frame_buffer ;
}
return i ; // handle for de-registering/locking
}
void displayDeregister( int handle )
{
if( handle >= 0 && handle < MAX_DISPLAY_THREADS )
{
display_registry[handle].frame_buffer = 0 ;
}
}
Note that the mutexes are not to lock the LCD resource, but to lock the shared memory frame buffer resources.
Other threads then simply place data for display in their own frame buffers, entirely asynchronously to the display of that data as follows for example:
displayLock( my_display_handle ) ;
update_display_buffer() ;
displayUnlock( my_display_handle ) ;
As mentioned in previous answers, first make a single task for LCD display then use timer events to track the time slice.
Finally, Yield the task in the timer event handler (called after the time slice).
If you don't know about yield, yield is a way for a task to give up its execution to enable scheduler to move to next task.

how to stop looping and wait until different value received from serial

hi i planning to made a multiple servo controlling with serial as control trigger signal on AVR with C and codevision
but when the trigger is true, the servo running in crazy loop, it back to original position (0 degree) instead of stay on desired position, my tutor give me hint to use "wait ... until" statement with the old data comparison but i'm not found the way to utilize it yet on google
because utilizing break; at the end of the if left the chip freeze until it reset
and the old code(it runs the servo forth and back continously)
while (1)
{
while(UCSRA & (1<<RXC))
{
// Place your code here
//data=UDR;
PORTC=UDR;
data=UDR;
//PORTB=data;
} ;
if (data== 0x0A || data== 0x0B)
{
if (data== 0x0A)
{
old_data=data;
PORTA=0x00;
PORTA.1=1;
movservo0(90,7);
movservo1(15,3);
}
if (data== 0x0B)
{
old_data=data;
PORTA=0x00;
PORTA.1=1;
movservo0(15,3);
movservo1(90,7);
}
}
}
as for movservo0 (another movservo() almost had same code)
void set_servo1(unchar derajat)
{ unchar n;
servo2=1;
delay_us(750);
for(n=0; n<derajat; n++)
{
delay_us(12);
};
servo2=0;
delay_ms(10);
}
void movservo0(unsigned char sudut, unsigned char speed)
{
unchar i;
set_servo1(sudut);
for (i=1;i<=sudut;i+=speed){
set_servo1(i);
delay_ms(100/speed);
}
}
This new code is a bit better.
The top of the while(UCSRA & (1<<RXC)) loop is fine this way. The loop body will only be entered if there is a character to be read. (Although, I'm not sure why you are expecting to read '\n' or vertical tab.)
A minor problem is the way the UDR is read. The act of reading UDR erases the contents. So you should be using
data=UDR;
PORTC=data;
The jumping of the servos appears to be in the moveservo() function. This function always sets the angle to 1 and then gradually increases the angle of the servo until it reaches the desired angle.
setservo() appears to be an attempt to perform PWM to drive a servo, but it doesn't work correctly. To keep the servo at a desired angle, you have to keep switching the pin from 0 to 1 at the correct times, not just once like this function does. Have you looked at the PWM functions of the timers? You just set these up and they run in the background. An alternative is to use a timer to set an interrupt to wake up and toggle the pins as you need.
If you want to do the switching of the pins without interrupts, then you should be using delays in the while(1) loop itself. Just use the setservo() functions to change some variables.
while(1)
{
// read the UART if ready and set the target values
// this part only runs occasionally
while(UCSRA & (1<<RXC))
{
// etc
}
// The rest of the loop body runs every time
// adjust the servo values toward the target values
// use a counter to determine if to adjust during this loop iteration
// e.g., a slow speed counts to a higher number before adjusting
delay(750);
for(int i = 0; i < NUM_INTERVALS; ++i)
{
// decide whether to set pins to 1 or 0 based on the servo values
delay(INTERVAL);
}
}
I don't know about your particular servos, but they typically have a period where most of the time the pin is 0, and then a short time in the period where the pin is 1. You will need to adjust NUM_INTERVALS and INTERVAL and 750 to add up to the correct length of time.
There is so much wrong with this snippet, it is hard to start. It is difficult to say why the servo is moving, as it is only ever "moved" to the same value every time. (Unless, you have omitted some code that sets it to some other value.)
Typically, when receiving UART, the processor should wait until the character is received. This is accomplished by this
while(UCSRA & (1<<RXC) == 0);
Note the ; creating an empty body of the while loop. This is probably what your tutor meant. When the flag is set, then the loop exits and the data is ready to be read.
while(UCSRA & (1<<RXC) == 0);
data = UDR;
Next, you have a block which looks like you meant to be part of a while loop, but it isn't. The body of the loop is the single statement abbove it. The block gets executed every time.
{
if(data=0x0a)
{
olddata=data;
movservo0(90,7); //move servo to certain degree
}
}
Another error is the condition in the if statement. It looks like you are trying to test if data is 0x0A, but that is not what is happening. Instead, you set data to be 0x0A, and then execute the inner part every time. The condition you probably want is if(data == 0x0A). Note the == instead of =.
So your code is equivalent to
while(1)
{
while(ucsra & (1<<RXC)) data=udr; // maybe read UDR into data
data=0x0a; // set data anyway
olddata=data;
movservo0(90,7); //move servo to certain degree
}
Again, for the jumping servo, I suspect some code that is omitted here that is also runs every time. Or else, the moveservo() function has a problem itself.

Do something, but check if button is clicked all the time

I have a arduino i want to blink some led light if the button is not clicked. Here is the code.
void startup(){
for (int x=0; x<=1;){
BUTTON5_state = digitalRead(START_BUTTON);
if (BUTTON5_state == HIGH ){
x++;
}
else{
blinkAll(1, 2000);
continue;
}
The problem is that its not checking the button often enough. The blink all 500 is waiting 2 seconds between each time it blinks. So you need to hold the button down for to seconds.
I want the light to blink every 2 second, but check the button "all the time". Is this possible?
Have you checked the "Blink Without Delay" tutorial in the Arduino IDE? Well, that's what you want to implement. Instead of using a delay (which is blocking) you poll the button as fast as possible and then, if millis() says that enough time has passed, you can blink.
delay is used when you want to wait; if you want to do something use other techniques.
An alternative is to use interrupts, but i suggest you to go with the first method...
2 possible solutions: create a thread, which checks the button and the original thread let the led blink. or you do the for loop faster and toggle the led only each 1000th iteration or so.
for example something like this:
for (int x=0; x<=100000;x++){
//wait to make the 1024 iteration blinking visible
BUTTON5_state = digitalRead(START_BUTTON);
if (BUTTON5_state == HIGH ){
break;
}
else if (x & (1 << 10)){ //each 1024th iteration
toggleLed();
}
}

Resources