C 计算平均值
当平均值应始终介于0和1之间时,从圆形阵列计算的运行平均值产生常数<0平均值 我正在为MSP430设备编写固件,该设备使用LED和光电二极管来检测墨水上的特定类型。该设备的扫描速度约为155us,扫描仪下的样本速度范围为.1m/s至3.3m/s。该设备的目标是测试油墨和测量油墨通过率,以测试不通过率,当比率在相应值之间时,打开绿色LED,当比率不在相应值之间时,打开红色LED。我使用静态整数数组将连续过程的值和测试值存储到每个数组的相同索引号。在数组的最后一个索引之后,索引被设置回零,旧值被写入 绿色LED灯亮;类似的定义是我的MCU的端口定义,并且经过验证是正确的 事件是测试结果。如果检测到墨水,则事件=检测到,反之亦然 测试将是GUI设置的平均值,但现在它什么都不是,因为我的函数的这一部分没有工作 通常情况下,我会通过附带的GUI设置变量平均值,但出于测试目的,我设置了averagesize,因为在我的代码中,n++将等于7,这是不允许的 我添加了一段代码以确保不会发生翻滚。选择值8000和30000以匹配最慢的运行速度 我还更改了数组索引递增的位置,并确保它显示在数组的范围内 以下是更新后的函数:C 计算平均值,c,arrays,msp430,circular-buffer,code-composer,C,Arrays,Msp430,Circular Buffer,Code Composer,当平均值应始终介于0和1之间时,从圆形阵列计算的运行平均值产生常数=大小n=0;则在顶部执行此操作;。这仍然允许n的大小为1 但是,再往下看,在访问数组之前不需要使用n++。这将允许您访问数组[size],它是UB 我相信在完成计算后,您希望将n++移到if部分的底部。并且,您可能希望将两者结合使用,如果++n>=size n=0 更新: 我将大小设置为5,但仍然得到负数。数组都在边界内,对吗 可能吧。但是,有几件事 只有平均值需要(或应该)浮动 你有并行阵列。我会使用struct 我已经仔细考
void display(char event, char test) {
static int size=5;
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 (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];
flag=1;
consecpass++;
n++;
if(n>=size)n=0;
//GREEN_LED_ON;
//RED_LED_OFF;
}else{
consecfail=0;
consecpass++;
//GREEN_LED_ON;
//RED_LED_OFF;
}
} 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];
flag=0;
consecfail++;
n++;
if(n>=size)n=0;
//RED_LED_ON;
//GREEN_LED_OFF;
}else{
consecpass=0;
consecfail++;
//RED_LED_ON;
//GREEN_LED_OFF;
}
}
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];
consecpass=0;
n++;
if(n>=size)n=0;
}
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];
consecfail=0;
n++;
if(n>=size)n=0;
}
average=sum/counter;
if(average<.6 && average > .1)
{
GREEN_LED_ON;
RED_LED_OFF;
}else{
GREEN_LED_OFF;
RED_LED_ON;
}
}
以下是原始代码:
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) {
n++;
sum = sum - array[n];
counter = counter - totalnumberoftests[n];
array[n] = 0;
totalnumberoftests[n] = consecfail;
sum = sum + array[n];
counter = counter + totalnumberoftests[n];
flag = 1;
consecpass++;
} else {
consecfail = 0;
consecpass++;
}
}
if (event == NOT_DETECTED) {
if (flag == 1) {
n++;
sum = sum - array[n];
counter = counter - totalnumberoftests[n];
array[n] = consecpass;
totalnumberoftests[n] = consecpass;
sum = sum + array[n];
counter = counter + totalnumberoftests[n];
flag = 0;
consecfail++;
} else {
consecpass = 0;
consecfail++;
}
}
average = sum / counter;
if (average < 0) {
GREEN_LED_ON;
RED_LED_OFF;
} else {
GREEN_LED_OFF;
RED_LED_ON;
}
}
你有UB
如果n>=大小n=0;则在顶部执行此操作;。这仍然允许n的大小为1
但是,再往下看,在访问数组之前不需要使用n++。这将允许您访问数组[size],它是UB
我相信在完成计算后,您希望将n++移到if部分的底部。并且,您可能希望将两者结合使用,如果++n>=size n=0
更新:
我将大小设置为5,但仍然得到负数。数组都在边界内,对吗
可能吧。但是,有几件事
只有平均值需要(或应该)浮动
你有并行阵列。我会使用struct
我已经仔细考虑过你的逻辑好几次了,但我仍然不确定你想达到什么目的
因此,我进行了重构,试图消除任何可能的小错误
我对计数器的减法加法有点怀疑,尤其是在转换点。这是唯一可以得到负数的地方
也许将函数插入模拟不同长度墨水/无墨水流数据的单元测试程序会有所帮助。然后,您可以中断一些事情。这可以测试/验证您的逻辑,而无需使用实时系统,也就是说,单元测试程序是一个普通的应用程序,您可以在PC上运行。您可以有条件地编译输入/输出LED代码,而不是下面提到的负值中止
不管怎么说,这里是我对简化的看法,这可能有助于澄清[请原谅这种无缘无故的风格清理]:
// NOTE: in the long term, an int could wrap to a negative -- adjust this
// as needed
typedef long long ctr;
struct event {
ctr testcount;
ctr passcount;
};
// NOTE: moved this outside function to guarantee all values are zero at start
#define EVENTMAX 6
struct event events[EVENTMAX];
void
display(char event, char test)
{
static int n = 0;
static ctr sum = 0; // total number of passes
static double average; // average pass rate over n
static ctr consecpass = 0; // consecutive passes
static ctr consecfail = 0; // consecutive fails
static ctr testcount = 1; // used to count the total number of tests
static int flag = 0;
struct event *cur;
cur = &events[n];
if (event == DETECTED) {
if (flag == 0) {
sum -= cur->passcount;
testcount -= cur->testcount;
cur->passcount = 0;
cur->testcount = consecfail;
sum += cur->passcount;
testcount += cur->testcount;
flag = 1;
if (++n >= EVENTMAX)
n = 0;
}
else {
consecfail = 0;
}
consecpass++;
}
if (event == NOT_DETECTED) {
if (flag == 1) {
sum -= cur->passcount;
testcount -= cur->testcount;
cur->passcount = consecpass;
cur->testcount = consecpass;
sum += cur->passcount;
testcount += cur->testcount;
flag = 0;
if (++n >= EVENTMAX)
n = 0;
}
else {
consecpass = 0;
}
consecfail++;
}
// add code to abort program if _either_ sum _or_ testcount is negative
// here ...
average = sum;
average /= testcount;
if (average < 0) {
GREEN_LED_ON;
RED_LED_OFF;
}
else {
GREEN_LED_OFF;
RED_LED_ON;
}
}
更新2:
我发现其中一个问题是翻车。我用一个if语句修复了这个问题,如果值大于8000或30000,它将存储这些值。当我处于调试模式时,数组的值看起来和我期望的一样,但我偶尔会在sum和counter中得到负数。错误的索引怎么会被减去呢 即使索引是有效的,也可以从过期条目中减去。我知道你在尝试一个RLE impl 猜测 您可以更改当前条目,但在++n之后,另一方可能会在需要上一个条目时获得下一个条目 也就是说,减去数组[0],应用填充,设置数组[0],然后增加n 另一方现在正在减去数组[1],此时它需要减去数组[0]并设置数组[1] 所以,从逻辑上讲,你可能会有一个错误 不知道 使用单元测试应用程序,您可以为所有内容添加调试printf。当出现负值时,停止。然后分析日志。单元测试可以/应该测试所有边缘情况 如果向函数中输入一个序列,例如1x10、0x3、1x5、0x20,则这些序列应显示在数组/结构中。存储的条目应与输入序列匹配 因此,转储数组以验证计数是否符合预期
什么值达到8000/30000?如果有人回到这一点,这就是我正在使用的代码,我的平均运行时间是完美的
void display(char event, char test) {
static int size=9; //size of the array
static int array[10]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //array with number of passes for each n
static int n=0; //number for the index in both arrays
static long int sum=0;//total of passes
static double average=0;//rate of passes per tests. The sum of the values in array[n] divided by total tests in totalnumberoftest[n] attay
static int consecpass=0; //consecutive passes
static int consecfail=0; //consecutive fails
static int totalnumberoftests[10]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //total number of tests conducted. Counts the number of passing or failing tests for the nth value
static long int counter=1; //used to count the total number of tests
static int flag=0;//flag used to indicate when the input goes from event==DETECTED to event==NOT_DETECTED
static int lowlimitb=0;// integer value from low limit b in desert for average setting. Value entered should be the positive tests/total tests percentage
sum=sum-(float)array[n]; //subtract the nth value of array from sum
counter=(float)counter-totalnumberoftests[n];
array[n]=0;//set the nth value to zero, because the previous state of event was NOT_DETECTED, meaning there were no positive tests
totalnumberoftests[n]=consecfail; //add the number of negative tests to total tests
sum=sum+(float)array[n]; //add array index n to sum (should be zero)
counter=counter+(float)totalnumberoftests[n]; //counter is the total number of tests. Add totalnumberoftests with the last index n adds the last consecfail to counter
flag=1; //set flag==1 to indicate the last event was DETECTED
consecpass++; //count a pass
consecfail=0;
n++; //set the next index for the arrays
if(n>size)n=0; //if array index is greater than the size of the array, set the index back to zero. This will overwrite the data in array index zero
//GREEN_LED_ON;
//RED_LED_OFF;
}else{ //the last event=DETECT, no need to change array indices
consecpass++;
//GREEN_LED_ON;
//RED_LED_OFF;
}
} if (event==NOT_DETECTED){
if(flag==1) //flag gets set to 1 in event==DETECTED
{
sum=sum-(float)array[n]; //subtract the nth value of array from current sum of passes
counter=counter-(float)totalnumberoftests[n];
array[n]=consecpass; //set array[n] equal to the number of consecutive passes
totalnumberoftests[n]=consecpass; //set the number of tests for index n = number of passes
sum=sum+(float)array[n]; //add the last number of consecutive passes (stored in array[n]) to the current sum of passes
counter=counter+(float)totalnumberoftests[n];
flag=0; //set the flag==0 so the array indices do not change until event changes
consecfail++;
n++; //set the next index for the arrays
if(n>size)n=0;//if array index is greater than the size of the array, set the index back to zero. This will overwrite the data in array index zero
//RED_LED_ON;
//GREEN_LED_OFF;
}else{
consecpass=0;
consecfail++;
//RED_LED_ON;
//GREEN_LED_OFF;
}
}
if (consecpass>8000) //used to prevent rollover and to indicate failure if device is standing still. 8000 was selected because the absolute minimum speed will be 10cm/s
{
sum=sum-(float)array[n];
counter=counter-(float)totalnumberoftests[n];
array[n]=consecpass;
totalnumberoftests[n]=consecpass;
sum=sum+(float)array[n];
counter=counter+(float)totalnumberoftests[n];
consecpass=0;
n++;
if(n>size)n=0;
}
if(consecfail>30000) //used to prevent rollover and to indicate failure if device is standing still. 30000 was selected because the absolute minimum speed will be 10cm/s
{
sum=sum-(float)array[n];
counter=counter-(float)totalnumberoftests[n];
array[n]=0;
totalnumberoftests[n]=consecfail;
sum=sum+(float)array[n];
counter=counter+(float)totalnumberoftests[n];
consecfail=0;
n++;
if(n>size)n=0;
}
average=(double)sum/(double)counter; //average is a float. The total number of positive tests/total number of tests
if(average<.35 && average > .25 //acceptable passing range
{
GREEN_LED_ON;
RED_LED_OFF;
} else {
GREEN_LED_OFF;
RED_LED_ON;
}
}
}
撇开糟糕的格式和奇怪的命名不谈,您没有提供一个简单的问题,也没有一个具体的问题。看起来像是一个“调试我的代码”请求,它与主题无关。MSP430可以使用专有工具和免费工具进行很好的调试。因此,启动调试器并单步执行代码。我认为一个基本问题是形式和函数的混合
. 将输入数据分析与其报告完全分开。混合它们会导致混乱。@WeatherVane您的意思是将从事件传递到LED的数据与输出分开吗?我的意思是将输入检测与处理与输出混合。@WeatherVane我应该有单独的功能吗?这样做有什么好处?我发现其中一个问题是滚动。我用一个if语句修复了这个问题,如果值大于8000或30000,它将存储这些值。当我处于调试模式时,数组的值看起来和我期望的一样,但我偶尔会在sum和counter中得到负数。错误的索引怎么会被减去呢?非常感谢你的帮助。墨水放置和移动的物理测试定义是,最大阳性测试时间应为8000左右,阴性测试时间应为30000左右。我对你发布的答案感到困惑,但一旦我尝试理解它,我将实现并测试它。我很难理解你的代码。在//addcode here to abort program if negative部分,我添加了ifsum<0 | | testcount
void display(char event, char test) {
static int size=9; //size of the array
static int array[10]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //array with number of passes for each n
static int n=0; //number for the index in both arrays
static long int sum=0;//total of passes
static double average=0;//rate of passes per tests. The sum of the values in array[n] divided by total tests in totalnumberoftest[n] attay
static int consecpass=0; //consecutive passes
static int consecfail=0; //consecutive fails
static int totalnumberoftests[10]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //total number of tests conducted. Counts the number of passing or failing tests for the nth value
static long int counter=1; //used to count the total number of tests
static int flag=0;//flag used to indicate when the input goes from event==DETECTED to event==NOT_DETECTED
static int lowlimitb=0;// integer value from low limit b in desert for average setting. Value entered should be the positive tests/total tests percentage
sum=sum-(float)array[n]; //subtract the nth value of array from sum
counter=(float)counter-totalnumberoftests[n];
array[n]=0;//set the nth value to zero, because the previous state of event was NOT_DETECTED, meaning there were no positive tests
totalnumberoftests[n]=consecfail; //add the number of negative tests to total tests
sum=sum+(float)array[n]; //add array index n to sum (should be zero)
counter=counter+(float)totalnumberoftests[n]; //counter is the total number of tests. Add totalnumberoftests with the last index n adds the last consecfail to counter
flag=1; //set flag==1 to indicate the last event was DETECTED
consecpass++; //count a pass
consecfail=0;
n++; //set the next index for the arrays
if(n>size)n=0; //if array index is greater than the size of the array, set the index back to zero. This will overwrite the data in array index zero
//GREEN_LED_ON;
//RED_LED_OFF;
}else{ //the last event=DETECT, no need to change array indices
consecpass++;
//GREEN_LED_ON;
//RED_LED_OFF;
}
} if (event==NOT_DETECTED){
if(flag==1) //flag gets set to 1 in event==DETECTED
{
sum=sum-(float)array[n]; //subtract the nth value of array from current sum of passes
counter=counter-(float)totalnumberoftests[n];
array[n]=consecpass; //set array[n] equal to the number of consecutive passes
totalnumberoftests[n]=consecpass; //set the number of tests for index n = number of passes
sum=sum+(float)array[n]; //add the last number of consecutive passes (stored in array[n]) to the current sum of passes
counter=counter+(float)totalnumberoftests[n];
flag=0; //set the flag==0 so the array indices do not change until event changes
consecfail++;
n++; //set the next index for the arrays
if(n>size)n=0;//if array index is greater than the size of the array, set the index back to zero. This will overwrite the data in array index zero
//RED_LED_ON;
//GREEN_LED_OFF;
}else{
consecpass=0;
consecfail++;
//RED_LED_ON;
//GREEN_LED_OFF;
}
}
if (consecpass>8000) //used to prevent rollover and to indicate failure if device is standing still. 8000 was selected because the absolute minimum speed will be 10cm/s
{
sum=sum-(float)array[n];
counter=counter-(float)totalnumberoftests[n];
array[n]=consecpass;
totalnumberoftests[n]=consecpass;
sum=sum+(float)array[n];
counter=counter+(float)totalnumberoftests[n];
consecpass=0;
n++;
if(n>size)n=0;
}
if(consecfail>30000) //used to prevent rollover and to indicate failure if device is standing still. 30000 was selected because the absolute minimum speed will be 10cm/s
{
sum=sum-(float)array[n];
counter=counter-(float)totalnumberoftests[n];
array[n]=0;
totalnumberoftests[n]=consecfail;
sum=sum+(float)array[n];
counter=counter+(float)totalnumberoftests[n];
consecfail=0;
n++;
if(n>size)n=0;
}
average=(double)sum/(double)counter; //average is a float. The total number of positive tests/total number of tests
if(average<.35 && average > .25 //acceptable passing range
{
GREEN_LED_ON;
RED_LED_OFF;
} else {
GREEN_LED_OFF;
RED_LED_ON;
}
}
}