How can I find a difference between two previous values inside an array, if I say that I'm counting how many values do I need to insert to full fill the array? Assume that we have an array with 5
elements. If I specify index 0
, then I need to take index 4 - index 3
because they are the two previous elements. If I specify index 1
, then I need to take index 0 - index 4
. And if I specify index 4
, then I need to take index 4 - index 3
again.
I have written a C code for that and my question is...if there are a better way to minimize this C code?
#include <stdio.h>
#include <stdint.h>
#define LEN 10
uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};
int main()
{
for(int i = LEN; i >= 0; i--){
int i0, i1;
int left = i;
if(LEN == left){
i0 = LEN - 2;
i1 = LEN - 1;
}else if(0 == left){
i0 = LEN - 2;
i1 = LEN - 1;
}else if(1 == LEN - left){
i0 = LEN - 1;
i1 = 0;
}else{
i0 = LEN - left - 2;
i1 = LEN - left - 1;
}
printf("i0 = %i, i1 = %i. Difference = %i\n", i0, i1, myArray[i1] - myArray[i0]);
}
return 0;
}
Example how I'm doing now. But it won't work perfectly for me due to wrong indexing.
#define LENGTH_ARRAY 5
static uint16_t input_capture0[LENGTH_ARRAY] = {0};
static uint16_t input_capture1[LENGTH_ARRAY] = {0};
static TIM_HandleTypeDef* handler_tim17;
static TIM_HandleTypeDef* handler_tim16;
void STM32_PLC_Input_Capture(TIM_HandleTypeDef* htim17, TIM_HandleTypeDef* htim16) {
/*
* Input capture for measuring frequency
* For TIM17 and TIM16
* Timer clock: 48 Mhz
* Prescaler: 4799
* Counter: 65535 (0xffff)
* Update frequency: 0.1526 Hz (1/0.1526 = 6.5535 seconds)
* Example: For every second, it will count 10000
* Lowest frequency measurement: 1/(0xFFFF*0.0001) = 0.1526 Hz
* Highest frequency measurement: 1/(1*0.0001) = 10000 Hz
*/
if(HAL_TIM_IC_Start_DMA(htim16, TIM_CHANNEL_1, (uint32_t*)input_capture1, LENGTH_ARRAY) != HAL_OK)
Error_Handler();
if(HAL_TIM_IC_Start_DMA(htim17, TIM_CHANNEL_1, (uint32_t*)input_capture0, LENGTH_ARRAY) != HAL_OK)
Error_Handler();
/* Save */
handler_tim17 = htim17;
handler_tim16 = htim16;
}
static uint16_t compute_period(uint16_t input_capture[], uint8_t elements_left_to_write_in_array) {
uint8_t index0, index1;
switch(elements_left_to_write_in_array){
case 5:
/* When the whole array has been filled by DMA and we stand at index 0, then we need to use the 2 past indexes */
index0 = 3;
index1 = 4;
case 4:
index0 = 4;
index1 = 0;
case 3:
index0 = 0;
index1 = 1;
case 2:
index0 = 1;
index1 = 2;
case 1:
index0 = 2;
index1 = 3;
default:
index0 = 0;
index1 = 1;
break;
}
return input_capture[index1] - input_capture[index0];
}
uint16_t STM32_PLC_Input_Capture_Get_Raw(uint8_t i){
if(i == 0)
return compute_period((uint16_t*)input_capture0, (uint8_t)handler_tim17->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
else
return compute_period((uint16_t*)input_capture1, (uint8_t)handler_tim16->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
}
CodePudding user response:
myArray
is a cyclic array. You want wrapping indexing, which is behavior we can get using %
operator:
#include <stdio.h>
#include <stdint.h>
#define LEN 10
uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};
int main()
{
for(int i = LEN; i >= 0; i--){
int i0 = ((i LEN) - 2) % LEN;
int i1 = ((i LEN) - 1) % LEN;
printf("i0 = %i, i1 = %i, i = %i Difference = %i\n",
i0, i1, i, myArray[i1] - myArray[i0]);
}
return 0;
}
Output
i0 = 8, i1 = 9, i = 10 Difference = 6
i0 = 7, i1 = 8, i = 9 Difference = -8
i0 = 6, i1 = 7, i = 8 Difference = 2
i0 = 5, i1 = 6, i = 7 Difference = 2
i0 = 4, i1 = 5, i = 6 Difference = 1
i0 = 3, i1 = 4, i = 5 Difference = -5
i0 = 2, i1 = 3, i = 4 Difference = 2
i0 = 1, i1 = 2, i = 3 Difference = 5
i0 = 0, i1 = 1, i = 2 Difference = -3
i0 = 9, i1 = 0, i = 1 Difference = -2
i0 = 8, i1 = 9, i = 0 Difference = 6
As you can see, i
always precedes i1
which itself precedes i0
.
Note that output from running the code above won't match yours, because yours doesn't exhibit the behavior you're describing.