Circular Array Stuck in if statements - c

I am writing firmware for an MSP430 device that uses LEDs and photodiodes to detect specific types on ink. The device scans at about 155us and the samples under the scanner range from velocities of .1m/s to 3.3m/s. The goal of the device is to test for ink and measure the ink (pass) to test (not pass) ratio and turn on a green LED when the ratio is between the corresponding value and turn on a red LED when it is not. I am using static integer arrays to store the values of consecutive passes and test values to the same index number of each array. After the last index of the array, the index is set back to zero and the old values are written over.
GREEN_LED_ON; and similar definitions are port definitions for my MCU and are verified to be correct.
event is the test result. If ink is detected, event=DETECTED and vice versa
test will be the average set by a GUI, but for now it is nothing because I don't have this part of my function working
Normally, I will not have GREEN_LED_ON; etc in the if(event) loops, but I put them there to visual where my code is going wrong. The code seems to get stuck in which ever loop even starts with. For example, if I start with the device over no ink, the LED stays red, and when the device is over ink, the device stays green no matter what. Does anyone have any idea what I am doing wrong and how to fix it?
Notes:
*I also tried changing the while(event)s to if statements and I get the same result
*When I comment the arrays inside the if statements, the code works as expected
*Top version is the current portion of the code and the bottom is what I started with
void display(char event, char test) {
static int size=6;
static int array[6]={0}; //array with number of passes for each n
static int n=0;
static float sum=0;//total number of passes
static float average=0;//average pass rate over n
static int consecpass=0; //consecutive passes
static int consecfail=0; //consecutive fails
static int totalnumberoftests[6]={0}; //total number of tests conducted. Counts the number of passing or failing tests for the nth value
static float counter=1; //used to count the total number of tests
static int flag=0;
if(n==size) n=0;
if (event == DETECTED)
{
if (flag==0)
{
sum=sum-array[n];
counter=counter-totalnumberoftests[n];
array[n]=0;
totalnumberoftests[n]=consecfail;
sum=sum+array[n];
counter=counter+totalnumberoftests[n];
n++;
}
consecfail=0;
consecpass++;
//GREEN_LED_ON;
//RED_LED_OFF;
flag=1;
} if (event==NOT_DETECTED){
if(flag==1)
{
sum=sum-array[n];
counter=counter-totalnumberoftests[n];
array[n]=consecpass;
totalnumberoftests[n]=consecpass;
sum=sum+array[n];
counter=counter+totalnumberoftests[n];
n++;
}
//array[n]=consecpass;
//totalnumberoftests[n]=consecpass;
consecpass=0;
consecfail++;
flag=0;
//GREEN_LED_OFF;
//RED_LED_ON;
}
if (consecpass>8000)
{
sum=sum-array[n];
counter=counter-totalnumberoftests[n];
array[n]=consecpass;
totalnumberoftests[n]=consecpass;
sum=sum+array[n];
counter=counter+totalnumberoftests[n];
n++;
}
if(consecfail>30000)
{
sum=sum-array[n];
counter=counter-totalnumberoftests[n];
array[n]=0;
totalnumberoftests[n]=consecfail;
sum=sum+array[n];
counter=counter+totalnumberoftests[n];
n++;
}
average=sum/counter;
if(average<1 && average >0 )
{
GREEN_LED_ON;
RED_LED_OFF;
}else{
GREEN_LED_OFF;
RED_LED_ON;
}
}
This was what I originally started with:
void display(char event, char test) {
static int size=6;
static int array[6]={0}; //array with number of passes for each n
static int n=0;
static int sum=0;//total number of passes
static double average=0;//average pass rate over n
static int consecpass=0; //consecutive passes
static int consecfail=0; //consecutive fails
static int totalnumberoftests[6]={0}; //total number of tests conducted. Counts the number of passing or failing tests for the nth value
static float counter=0; //used to count the total number of tests
while(n<=size)
{
sum=sum-array[n]; //subtacts the nth value from the total sum of passing tests
counter=counter-totalnumberoftests[n]; //subtracts the nth value of the total number of tests run
if(event == DETECTED)
{
array[n]=0;
totalnumberoftests[n]=consecfail;
consecfail=0;
consecpass++;
GREEN_LED_ON;
RED_LED_OFF;
} if(event==NOT_DETECTED){
array[n]=consecpass;
totalnumberoftests[n]=consecpass;
consecpass=0;
consecfail++;
GREEN_LED_OFF;
RED_LED_ON;
}
sum=sum+array[n];
counter=counter+totalnumberoftests[n];
average=sum/counter;
/*if(average<1)
{
GREEN_LED_ON;
RED_LED_OFF;
}else{
GREEN_LED_OFF;
RED_LED_ON;
}*/
n++;
}
if(n>size) n=0;
}

*When I comment the arrays inside the if statements, the code works as expected
static int size=6;
static int array[6]={0}; //array with number of passes for each n
static int totalnumberoftests[6]={0};
and this
while(n<=size)
When n=6 you pass the array boundary - max index is 5 not 6 for those (min index = 0).
array[n]=0;
totalnumberoftests[n]=consecfail;
That is UB and this may produce invalid behavior.
Change condition in while to n < size.
Anyway this code seems "weird" to me.

To elaborate on my comment, if you are in an event-driven system, I expect there is some code (usually called an "event loop") somewhere that looks like this:
event_loop()
{
while (TRUE)
{
event = get_event_from_someplace(...);
display(...);
}
}
It may be that instead of calling display directly, there was some process where you register the event handler. But the upshot is that there is probably an endless loop in some library code that calls your function over and over and over again. So you don't need the while() in your code.
Your code should be a state machine that keeps track of internal state (using static variables, like you are) and then performs whatever updates are required for each call.
Something like this:
void display(char event, ...)
{
static int consecutive_passes = 0;
static int consecutive_fails = 0;
if (event == DETECTED) {
++consecutive_passes;
}
else if (event == NOT_DETECTED) {
++consecutive_fails;
}
else {
// What else is there?
}
}
The idea is that this code gets called every time there is an event, and it just updates whatever set of things need updating. But there is no while loop, because the calls are coming from the event loop, and that's all the while loop you need.

Related

C-How to increase in recursion?An example of recursively judging prime numbers

I'm a programming rookie who has not yet started. I just learned recursion and there are some problems with the use of recursion. There is a homework is judge prime numbers :using int prime(int x); and return boolean value.
Initially I found that because the variable is initialized and assigned inside the function,the program can't achieve self-increment. Because every time it enters a new level of recursion, the variable will be reassigned. Even if you write a variable auto-increment statement, it will only auto-increase the variables stored in the current recursive stack. Once the variable enters a new recursive level, the variable is only initialized according to the definition and cannot be continuously auto-incremented.
The solution to the failure is as follows:
#include <math.h>
#define false 0
#define true 1
int prime(int x){
double high=sqrt(x);
int low=2;
if((x%low==0 && x!=2) || low>high){
return false;
}
else if(x<2){
return false;
}
else{
return true;
}
low++;
return prime(x);
}
When asking questions, I found a successful solution:
#include <math.h>
#define false 0
#define true 1
int prime(int x){
double high=mysqrt(x);
static int low=2;
if((x%low==0 && x!=2)||low>high){
return false;
}
else if(x<2){
return false;
}
else{
return true;
}
low++;
return prime(x);
}
But I can't understand why using static to modify the variable can make the variable correctly increment when entering a new layer of recursion instead of executing the previous int low=2;
Ask the master to solve the confusion for me, what happened to the two in the memory space?
In addition, there seems to be another solution, which seems to be to set a flag variable, but I did not understand it. Can someone provide other solutions?
In a nutshell, ordinary variables (int low;) get created for each function call independently, while static (static int low = 2;) are created once and shared between all the functions.
However, static is not the best approach to use in such cases, because different function calls may need to have different values of high/low.
Instead, you may add explicit parameters to the function, something like this (the algorithm is wrong, but it's the general principle):
int prime(int x) { return prime_impl(x, 2, sqrt(x)); }
int prime_impl(int x, int low, double high) {
if(x<2) {
return false;
}
else if((x%low==0 && x!=2)||low>high) {
return true;
}
else {
return prime_impl(x, low+1, high);
}
}

Weird error/result when running code... C fdtd method

Whenever I initiate a for loop to give values to an array, it modifies the result in another loop despite not being called in that loop... The problem comes from epsR... somehow commenting/uncommenting it changes the result for the time stepping loop (calculating the elec/mag field). Why? When the for loop with espR in and the if statement is left commented out, the results are good. When not commented out, I get nonsense results!
Could it be like memory corruption? I don't see what could be causing the problem.
#include <stdio.h>
#include <math.h>
#define SIZE 200
int main()
{
double ez[SIZE]={0.}, hy[SIZE]={0.}, imp0=377.0;
double epsR[SIZE];
int qTime, maxTime=650, mm;
char basename[80]="sim", filename[100];
int frame=0;
FILE *snapshot;
/* Init */
for (mm=0;mm<SIZE;mm++){
ez[mm]=0.0;
}
for (mm=0;mm<SIZE-1;mm++){
hy[mm]=0.0;
}
/* Leaving this loop uncommented modifies the results
of the loop time stepping*/
for (mm=0;mm<SIZE;mm++){
if (mm<100){
epsR[mm]=1.0;
}
else {
epsR[mm]=9.0;
}
}
/* time stepping*/
for (qTime=0; qTime<maxTime;qTime++){
/*Mag field*/
hy[SIZE-1]=hy[SIZE-2];
for (mm=0;mm<SIZE-1;mm++){
hy[mm]=hy[mm]+(ez[mm+1]-ez[mm])/imp0;
}
hy[49]-=exp(-(qTime-30.)*(qTime-30.)/100.)/imp0;
/*Elec field*/
ez[0]=ez[1];
ez[SIZE-1]=ez[SIZE-2];
for (mm=0;mm<SIZE;mm++){
ez[mm]=ez[mm]+(hy[mm]-hy[mm-1])*imp0/9.0;
}
ez[50]+=exp(-(qTime+0.5-(-0.5)-30.)*(qTime+0.5-(-0.5)-30.0)/100.);
/*Write*/
if (qTime % 10==0){
sprintf(filename,"%s.%d", basename, frame++);
snapshot=fopen(filename,"w");
for (mm=0;mm<SIZE;mm++){
fprintf(snapshot,"%g\n",ez[mm]);
}
fclose(snapshot);
}
}
return 0;
}
In this loop:
for (mm=0;mm<SIZE;mm++){
ez[mm]=ez[mm]+(hy[mm]-hy[mm-1])*imp0/9.0;
}
in the first iteration, mm == 0
so hy[mm-1] is hy[-1] and that's the out of bounds undefined behavior. Meaning anything can happen, because it's accessing random data.
If you want it to be accessing the last element, check like so:
for (mm=0;mm<SIZE;mm++){
if(mm==0) {
ez[0]=ez[0]+(hy[0]-hy[SIZE - 1])*imp0/9.0;
} else {
ez[mm]=ez[mm]+(hy[mm]-hy[mm-1])*imp0/9.0;
}
}

Global variable does not work properly C

int counter = 0;
int main (void)
{
while(1)
{
counter++;
wait_ms(1000);
if(counter==5) Led_on();
putrsUSART("\n\rUSART: "); putiUSART(counter);
}
}
void putcUSART(u8 data)
{
//Wait until transmitt buffer is empty
while(! (USART1 -> SR & USART_SR_TXE));
//Send the data
USART1->DR = (data & 0xFF);
}
void putsUSART (u8 *data)
{
do{
putcUSART(*data);
}while (*data++);
}
void putiUSART (u32 value)
{
char TXBUFFER[32] = {0};
snprintf(TXBUFFER, sizeof(TXBUFFER), "%d",value);
putsUSART ((u8*)TXBUFFER);
}
I have a problem with the code above. Its so simple that I dont understand why it doesnt work.
If I place "int counter =0" inside the main loop (before while) then the counter counters correctly.
But now he does count but dont start by 0. But for example: 509888073;
I used a ARM32Fxx processor. Could it be a configuration fault?
A stab in the dark is that you're using an embedded compiler and your c-startup is not initialising the bss section. This would give the results you're seeing where local function variables are initialised, but statics are not.
To test if this is true, you can include counter in main again and mark it as static and you'll likely get the same result as it being global...
int main( void )
{
static int counter = 0;
...
Please show your compile + link commands. Ideally a pastebin of the disassembled exe would be good too.
Please check that the counter variable is extended some where and some other thread is using that variable while this thread in wait state. If it is working in inside the main means, this could be the reason
just try replacing the counter name with some other variable just to test if the counter is being used accidentally by some other thread.

Build a binary-heap from an array, which method is more efficient and why

I am learning about heaps and i have found two ways of building them from a given array:
I am trying to build up a MAX Heap.
1.Top to down approach
Here i just check for every element if it is at the correct position or not. By using a method called restoreUp, in which every key is compared to its parent key , and if the parent key is smaller than the parent key is moved down.This procedue continues till the parent key is greater.I check it for every key starting at index position 2.
My Code is:
void restoreUp(int arr[],int i)
{
int k=arr[i];
int par=i/2;
while(arr[par]<k)
{
arr[i]=arr[par];
i=par;
par=i/2;
}
arr[i]=k;
}
void buildheap1(int arr[],int size)
{
int i;
for(i=2;i<=size;i++)
restoreUp(arr,i);
}
Bottom up approach
Here i start from the first non leaf node present at index floor(size/2), and call a method restoreDown until node number 1.I compare a key with both its left and right child and then the greater child is moved up.If both children are greater than the key then move the larger of the 2 children up.This procedure stops when both children are smaller than the key.
My Code is:
void restoreDown(int arr[],int i,int size)
{
int left=2*i;
int right=2*i+1;
int num=arr[i];
while(right<=size)
{
if(num>arr[left] && num>arr[right])
{
arr[i]=num;
return;
}
else if(arr[left]>arr[right])
{
arr[i]=arr[left];
i=left;
}
else
{
arr[i]=arr[right];
i=right;
}
left=2*i;
right=2*i+1;
}
if(left==size && arr[left]>num)
{
arr[i]=arr[left];
i=left;
}
arr[i]=num;
}
void buildheap2(int arr[],int size)
{
int i;
for(i=size/2;i>=1;i--)
restoreDown(arr,i,size);
}
Both the methods are working for me.
I just wanted to know which method is more efficient and why?
Generally speaking with modern CPU (having caches). Reading and array backward is usually a very bad idea as it generates a lot of cache misses. Unless (of course) the array was already in cache.
So first approach seems to be better from that point of view.

Calling a function more than once

So I'm programming a PIC using a CCS compliler. I'm using timer interrupt and this interrupt calls a function, called chronometer, that I wrote twice. This is how it goes
void timer2_isr()
{
j++;
l++;
z++;
if (j==1)
{
timero=1;
btndly=1;
j=0;
}
user1= chronometer(x, l);
user2= chronometer(pad.deger, z);
}
This function returns a struct and takes 2 integers as an argument. It works fine, when I just call the function once. However when, as in this case, I call the function twice, user2 is just equal to whatever user1 is and the code is not even working correctly. Any idea why?
chrono chronometer(int enable, int milicounter)
{
chrono time;
if(enable==1 && milicounter>=25) // Eğer kronometre aktif haldeyse
{
milicounter=0;
time.sec++;
if(time.sec==60)
{
time.sec=0;
time.min++;
}
if(time.min==60)
{
time.min=0;
time.hour++;
}
if(time.hour==24)
time.hour=0;
}
return time;
}
It seems you are starting to use the time struct without resetting it's members, resulting in unexpected results..
And even if it is somehow initialized.. it does not refer to the input parameters, so obviously the result will be the same..

Resources