I am trying to enter an if statement when my counter reaches the value 51, and then increment the counter inside the if statement so that it is never true again:
void imu_raw_handler (const lcm_recv_buf_t *rbuf, const char *channel,
const imu_raw_t *msg, void *userdata) {
for(counter = 1; counter < 51; counter++)
{
gyro_roll = (gyro_roll + gyro_roll_old*(counter-1))/counter;
gyro_pitch = (gyro_pitch + gyro_pitch_old*(counter-1))/counter;
gyro_yaw = (gyro_yaw + gyro_yaw_old*(counter-1))/counter;
accel_x = (accel_x + accel_x_old*(counter-1))/counter;
accel_y = (accel_y + accel_y_old*(counter-1))/counter;
accel_z = (accel_z + accel_z_old*(counter-1))/counter;
}
if (counter == 51){
// set zero points
axo = accel_x;
ayo = accel_y;
azo = accel_z;
gro = gyro_roll;
gpo = gyro_pitch;
gyo = gyro_yaw;
printf("Ready for Takeoff\n");
counter++;
}
}
Edit: My main function looks like this. It is supposed to subscribe to a streaming topic for as long as it is running. I define a counter as a global variable.
int main()
{
lcm_t *lcm = lcm_create(NULL);
imu_raw_t_subscribe(lcm, "IMU_RAW", imu_raw_handler, NULL);
// Enter read loop
while (1) {
if(!lcm_handle_timeout(lcm, 1000)) {
printf("Failed read from IMU_RAW channel\n");
}
}
lcm_destroy(lcm);
}
But this will repeatedly print my message forever rather than making counter = 52 and never happening again. Why does this not work?
The problem most likely exists outside these code snippets. Please check if you have no prints somewhere else.
The problem is because you call that function in a while, and because of
for(counter = 1; counter < 51; counter++)
the counter will become again 51 (everytime the function is called) and then will enter again in that if (counter == 51).
To resolve that you could declare a global variable int ok = 0; and use it like this:
void imu_raw_handler (const lcm_recv_buf_t *rbuf, const char *channel,
const imu_raw_t *msg, void *userdata) {
for(counter = 1; counter < 51; counter++)
{
gyro_roll = (gyro_roll + gyro_roll_old*(counter-1))/counter;
gyro_pitch = (gyro_pitch + gyro_pitch_old*(counter-1))/counter;
gyro_yaw = (gyro_yaw + gyro_yaw_old*(counter-1))/counter;
accel_x = (accel_x + accel_x_old*(counter-1))/counter;
accel_y = (accel_y + accel_y_old*(counter-1))/counter;
accel_z = (accel_z + accel_z_old*(counter-1))/counter;
}
if (ok == 0){ //will enter here once, only if you don't modify the ok anytime
// set zero points
axo = accel_x;
ayo = accel_y;
azo = accel_z;
gro = gyro_roll;
gpo = gyro_pitch;
gyo = gyro_yaw;
printf("Ready for Takeoff\n");
ok = 1; //this will be done once
}
}
I hope this is correct.
The for loop right before the if uses the counter variable, so every time the loop is finished, counter will be 51.
My guess is that the loop shouldn't be there at all, it doesn't seem to make any sense.
Related
We have a project that controls a led strip of 80, that is connected via mobile app. The components we used are as follows:
Arduino Nano Board
HM - 10 Bluetooth module
WS2812b Led Strip
On the app, user selects the colors(up to 5), animation (optional), animation speed and brightness. The selected configuration is transmitted to the BLE module with a certain throttle and debouncing. The color(selected on a color wheel on the app) and brightness transmits fine, without any issues.
The problem we encounter, is that when certain animation is active, if the user changes the animation speed via the app, the arduino part locks itself and will not accept any more commands.
To activate a configuration with animation, we send the data from app to arduino as follows:
<l255180200,240135068:089;04200>
The format is: < [mode] [colors(with ',')] : [brightness] ; [animationCode(2 digit)] [animationSpeed] >
At first, we had some inconsistencies with consecutive data, so we implemented the following for data acquisition:
void loop()
{
// Read all serial data available, as fast as possible
while (bleSerial.available() > 0)
{
char inChar = bleSerial.read();
if (inChar == SOP)
{
index = 0;
inData[index] = '\0';
started = true;
ended = false;
}
else if (inChar == EOP)
{
ended = true;
break;
}
else
{
if (index < 79)
{
inData[index] = inChar;
index++;
inData[index] = '\0';
}
}
}
// We are here either because all pending serial
// data has been read OR because an end of
// packet marker arrived. Which is it?
if (started && ended)
{
// The end of packet marker arrived. Process the packet
Serial.println(inData);
Serial.println(inData[0]);
char mode = inData[0];
if (mode == 'p')
{
togglePower(inData);
finalizeRead();
return;
}
if (mode == 'b')
{
changeBrightness(inData);
finalizeRead();
return;
}
if (mode == 't')
{
char *themeNo = strtok(NULL, ";");
int themeCode = valueFromString(themeNo, 0, 2);
theme(themeCode);
}
// if (mode == 'e') {
// sound();
// return;
// }
char *colorsWithBrightness = strtok(inData, ";");
char *animation = strtok(NULL, ";");
char *colors = strtok(colorsWithBrightness, ":");
char *brightness = strtok(NULL, ":");
custom(colors, brightness, animation);
finalizeRead();
}
}
void finalizeRead()
{
// Reset for the next packet
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
int valueFromString(char *string, int start, int width)
{
int value = 0;
for (int n = 0; n < width; n++)
value = value * 10 + string[start + n] - '0';
return value;
}
So the custom function is called when the mode == 'l'. And in custom function, we perform as follows:
void custom(char *colors, char *brightness, char *animation)
{
char *trueColors = strtok(colors, "l");
char *colorsSplit = strtok(trueColors, ",");
int colorCount = 0;
uint32_t colorArray[5] = {};
while (colorsSplit != NULL)
{
int r = valueFromString(colorsSplit, 0, 3);
int g = valueFromString(colorsSplit, 3, 3);
int b = valueFromString(colorsSplit, 6, 3);
colorArray[colorCount] = strip.Color(r, g, b);
colorCount++;
colorsSplit = strtok(NULL, ",");
}
int ledsPerSegment = ledCount / colorCount;
for (int n = 0; n < colorCount; n++)
{
int currentSegment = (n + 1) * ledsPerSegment;
Serial.println(currentSegment);
for (int z = n * ledsPerSegment; z < (n + 1) * ledsPerSegment; z++)
{
strip.setPixelColor(z, colorArray[n]);
}
}
strip.setBrightness(atoi(brightness));
strip.show();
Serial.println("Done");
if (animation)
{
int animationCode = valueFromString(animation, 0, 2);
int animationSpeed = valueFromString(animation, 2, 3);
Serial.println(animationSpeed);
if (animationCode == 1)
breath(animationSpeed, atoi(brightness));
else if (animationCode == 7)
pulse(animationSpeed, colorArray, colorCount);
}
}
The problem occurs in pulse animation, which is like this:
void pulse(int wait, uint32_t colorArray[], int colorCount)
{
black();
while (bleSerial.available() <= 0)
{
for (i = 0; i < colorCount && bleSerial.available() <= 0; i++)
{
for (j = 0; j < ledCount / 2 && bleSerial.available() <= 0; j++)
{
strip.setPixelColor(39 - j, colorArray[i]);
strip.setPixelColor(40 + j, colorArray[i]);
strip.show();
delay(wait);
}
black();
}
}
}
We initialize the animation without any issues using the following:
<l255180200,240135068:089;04200>
As soon as we adjust the animation speed from the app, we send about 2 new configurations per second, which is the same as above, only with different speed (last 3 characters before '>'). The arduino part randomly receives the data incorrectly, losing 2-3 characters, which is like <l2551800,240135068:089;04200>
The loss of characters usually occurs on different parts of the string, but always consecutive characters are misread happen each time. Also, sometimes we get a backwards question mark.
We are not sure where we implement wrong, so any help is appreciated on solving this issue.
Thanks!
I have the following code which correctly calculates the jaccard similarity between an input char array and an existing array of char arrays. jacc_sim_rec[] is used to record the similarities which satisfy a minimum threshold value. The for loop is used to iterate through the multidimensional array and the loop is supposed to continue checking similarity if minimum threshold is not satisfied at if (jacc_sim < SIM_THRESHOLD); else record the result at
else
{
jacc_sim_rec[j] = jacc_sim;//keep record of similarity
++j;//record number of highly similar elements
}
my problem is, the whole statements in the else block is executed twice every time the threshold value is satisfied.
int j=0;
void calc_jac_sim( char*INCOMING, int grp)
{
unsigned long i, j11 = 0, j01 = 0, j10 = 0,m=0;
char *m11, *m01, *m10;
float jacc_sim = 0.0;
char r1[SBF_LEN] = { NULL };
char r2[SBF_LEN] = { NULL };
char r3[SBF_LEN] = { NULL };
int cnt = SBF_LEN - 1;
clear_jacc_sim_info();
for (int i = 0; i <= SBF_REC[grp]; ++i)
{
while (cnt >= 0)
{
r1[cnt] = SBF[grp][i][cnt] & INCOMING[cnt];
r2[cnt] = ~SBF[grp][i][cnt] & INCOMING[cnt];
r3[cnt] = SBF[grp][i][cnt] & ~INCOMING[cnt];
cnt--;
}
m11 = ( char*)r1;
m01 = ( char*)r2;
m10 = ( char*)r3;
for (m = SBF_LEN * sizeof( char); m--;
j11 += NumberOfSetBits(*m11++),
j01 += NumberOfSetBits(*m01++),
j10 += NumberOfSetBits(*m10++));
jacc_sim = j11 / (float)(j11 + j01 + j10);
if (jacc_sim < SIM_THRESHOLD);
//continue;//do nothing
else
{
jacc_sim_rec[j] = jacc_sim;//keep record of similarity
++j;//record number of highly similar elements
}
}
}
I don't understand the code, but I'll bet the problem is that you're not reinitializing cnt each time through the for loop, so you only fill in r1, r2, and r3 when i = 0.
Change that loop to:
for (int cnt = SBF_LEN - 1; cnt >= 0; cnt--)
{
r1[cnt] = SBF[grp][i][cnt] & INCOMING[cnt];
r2[cnt] = ~SBF[grp][i][cnt] & INCOMING[cnt];
r3[cnt] = SBF[grp][i][cnt] & ~INCOMING[cnt];
}
I'm also not sure why this needs to count down instead of up, like a typical loop, but it shouldn't make a difference.
The code block is from mozilla firefox's qcms transform_util.c
void build_output_lut(struct curveType *trc,
uint16_t **output_gamma_lut, size_t *output_gamma_lut_length)
{
if (trc->type == PARAMETRIC_CURVE_TYPE) {
float gamma_table[256];
uint16_t i;
uint16_t *output = malloc(sizeof(uint16_t)*256);
if (!output) {
*output_gamma_lut = NULL;
return;
}
compute_curve_gamma_table_type_parametric(gamma_table, trc->parameter, trc->count);
*output_gamma_lut_length = 256;
for(i = 0; i < 256; i++) {
output[i] = (uint16_t)(gamma_table[i] * 65535);
}
*output_gamma_lut = output;
} else {
if (trc->count == 0) {
*output_gamma_lut = build_linear_table(4096);
*output_gamma_lut_length = 4096;
} else if (trc->count == 1) {
float gamma = 1./u8Fixed8Number_to_float(trc->data[0]);
*output_gamma_lut = build_pow_table(gamma, 4096);
*output_gamma_lut_length = 4096;
} else {
//XXX: the choice of a minimum of 256 here is not backed by any theory,
// measurement or data, however it is what lcms uses.
*output_gamma_lut_length = trc->count;
if (*output_gamma_lut_length < 256)
*output_gamma_lut_length = 256;
*output_gamma_lut = invert_lut(trc->data, trc->count, *output_gamma_lut_length);
}
}
}
For this loop:
for(i = 0; i < 256; i++) {
output[i] = (uint16_t)(gamma_table[i] * 65535);
}
VC2013 will show:
e:\mozilla\hg\nightly\mozilla-central\gfx\qcms\transform_util.c(490) : info C5002: 由于“500”,循环未向量化
MSDN (http://msdn.microsoft.com/en-us/library/jj658585.aspx) shows:
// Code 500 is emitted if the loop has non-vectorizable flow.
// This can include "if", "break", "continue", the conditional
// operator "?", or function calls.
// It also encompasses correct definition and use of the induction
// variable "i", in that the increment "++i" or "i++" must be the last
// statement in the loop.
But the loop above has no if/break/continue, I don't know why it can't be vectorized.
I suspect that this is due to the fact that variable "i" lies in scope of "if"-statement. Thus it does not belong entirely to "for-loop" scope like it would have been in
for(int i = 0; /* etc. */
At such, the compiler's logic would have been like: "I need not only to make gammatable filles with needed values, but to assign same value to "i" as at loop end". Therefore, no vectorization.
I'm trying to make a simple assembler for a very simple MIPS processer. Unfortunately, C has been giving me a lot of trouble, specifically, strcasecmp has not been returning valid/correct results. The results are correct sometimes.. but usually not, and I can't grasp why in the world this would be the case. Beyond any suggestions for a fix, could someone explain why these errors are occurring?
NOTE I do not think the error is due to passing the register table. Same errors occur when register table is declared inside the convert register function
Thanks!!!
the function that should return the value corresponding to the register name. Note that RegisterTable is declared in main. I did this so I could iterate through and test every Register name in the table from main
int ConvertRegisterName(char * rname,REG_NAME_PAIR RegisterTable[32])
{
int i;
int j=0;
for (i=1; i<32; i++,i++)
{
if (!(strcasecmp(RegisterTable[i].reg_number,rname) & strcasecmp(RegisterTable[i].reg_name,rname)))
{
j=i;
return j;
break;
}
}
if(!j)
{
printf("Error with register name \n");
return j;
}
}
The main function
int main(int argc,char *argv[])
{
REG_NAME_PAIR RegisterTable[32];
RegisterTable[1].reg_name = "at";
RegisterTable[1].reg_number = "$1";
RegisterTable[2].reg_name = "v0";
RegisterTable[2].reg_number = "$2";
RegisterTable[3].reg_name = "v1";
RegisterTable[3].reg_number = "$3";
RegisterTable[4].reg_name = "a0";
RegisterTable[4].reg_number = "$4";
RegisterTable[5].reg_name = "a1";
RegisterTable[5].reg_number = "$5";
RegisterTable[6].reg_name = "a2";
RegisterTable[6].reg_number = "$6";
RegisterTable[7].reg_name = "a3";
RegisterTable[7].reg_number = "$7";
RegisterTable[8].reg_name = "t0";
RegisterTable[8].reg_number = "$8";
RegisterTable[9].reg_name = "t1";
RegisterTable[9].reg_number = "$9";
RegisterTable[10].reg_name = "t2";
RegisterTable[10].reg_number = "$10";
RegisterTable[11].reg_name = "t3";
RegisterTable[11].reg_number = "$11";
RegisterTable[12].reg_name = "t4";
RegisterTable[12].reg_number = "$12";
RegisterTable[13].reg_name = "t5";
RegisterTable[13].reg_number = "$13";
RegisterTable[14].reg_name = "t6";
RegisterTable[14].reg_number = "$14";
RegisterTable[15].reg_name = "t7";
RegisterTable[15].reg_number = "$15";
RegisterTable[16].reg_name = "s0";
RegisterTable[16].reg_number = "$16";
RegisterTable[17].reg_name = "s1";
RegisterTable[17].reg_number = "$17";
RegisterTable[18].reg_name = "s2";
RegisterTable[18].reg_number = "$18";
RegisterTable[19].reg_name = "s3";
RegisterTable[19].reg_number = "$19";
RegisterTable[20].reg_name = "s4";
RegisterTable[20].reg_number = "$20";
RegisterTable[21].reg_name = "s5";
RegisterTable[21].reg_number = "$21";
RegisterTable[22].reg_name = "s6";
RegisterTable[22].reg_number = "$22";
RegisterTable[23].reg_name = "s7";
RegisterTable[23].reg_number = "$23";
RegisterTable[24].reg_name = "t8";
RegisterTable[24].reg_number = "$24";
RegisterTable[25].reg_name = "t9";
RegisterTable[25].reg_number = "$25";
RegisterTable[26].reg_name = "k0";
RegisterTable[26].reg_number = "$26";
RegisterTable[27].reg_name = "k1";
RegisterTable[27].reg_number = "$27";
RegisterTable[28].reg_name = "gp";
RegisterTable[28].reg_number = "$28";
RegisterTable[29].reg_name = "sp";
RegisterTable[29].reg_number = "$29";
RegisterTable[30].reg_name = "fp";
RegisterTable[30].reg_number = "$30";
RegisterTable[31].reg_name = "ra";
RegisterTable[31].reg_number = "$31";
int i;
for (i=1; i<32; i++)
{
printf("i is %d\n",i);
printf("Register Name is %s \n" ,RegisterTable[i].reg_name);
printf("this is the return value %d",ConvertRegisterName(RegisterTable[i].reg_name,RegisterTable));
printf("\n");
printf("Register Number %s\n",RegisterTable[i].reg_number);
printf("this is the return value %d",ConvertRegisterName(RegisterTable[i].reg_number,RegisterTable));
printf("\n");
printf("\n");
}
}
The REG_NAME_PAIR struct
typedef struct
{
char *reg_name;
char *reg_number;
} REG_NAME_PAIR;
The conversion function could probably be simplified and corrected to something like this:
int ConvertRegisterDesc(const char * token, REG_NAME_PAIR RegisterTable[])
{
for (int i = 1; i != 32; ++i)
{
if (strcasecmp(RegisterTable[i].reg_number, token) == 0 ||
strcasecmp(RegisterTable[i].reg_name, token) == 0 )
{
return i;
}
}
printf("Error with register name \n");
return 0;
}
Now ConvertRegisterDesc("foo", RegisterTable) returns the index of an entry whose name or value is (a case variant of) "foo", and 0 if no such entry could be found.
You seem to be using the & operator instead of &&.
& does bitwise and, not logical and. So for example:
0x01 & 0x02 == 0 - because no bit is set on both
0x01 && 0x02 == 1 - because both 0x01 and 0x02 evaluate to true.
gcc 4.4.4 c89
I have the following code and 2 structures that have to be filled.
I have 3 functions that will fill the handles for each of the devices.
However, the device_type structure will need to increment from where the last function finished.
For example:
load_resources() starts at 0 and finishes at 9
dev_types starts at 0 and finishes at 9
load_networks() starts at 0 and finishes at 9
dev_types starts at 10 and finishes at 19
load_controls() starts at 0 and finishes at 9
dev_types starts at 20 and finishes at 29
However, as I don't want to use a static or global variable is there any way I can increment a
value for this. So it will start where the last function finished.
Many thanks for any suggestions,
#define NUMBER_OF_DEVICES 10
#define NUMBER_OF_TYPES 3 /* resources
networks
controls */
int events(int evt);
int load_resources();
int load_networks();
int load_controls();
static struct device_table {
int resource_handle;
int network_handle;
int control_handle;
} dev_tbl[NUMBER_OF_DEVICES];
struct device_types {
size_t id;
int dev_handle;
int dev_type;
}dev_types[NUMBER_OF_DEVICES * NUMBER_OF_TYPES];
enum dev_name_types {RESOURCE, NETWORK, CONTROL};
/* Simulates the API calls, by returning a dummy handle */
int get_resources();
int get_networks();
int get_controls();
int main(void)
{
srand(time(NULL));
load_resources();
load_networks();
load_controls();
return 0;
}
int load_resources()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].resource_handle = get_resources();
printf("dev_tbl[i].resource_handle [ %d ]\n", dev_tbl[i].resource_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].resource_handle;
dev_types[i].dev_type = RESOURCE;
}
}
int load_networks()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].network_handle = get_networks();
printf("dev_tbl[i].network_handle [ %d ]\n", dev_tbl[i].network_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].network_handle;
dev_types[i].dev_type = NETWORK;
}
}
int load_controls()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].control_handle = get_controls();
printf("dev_tbl[i].control_handle [ %d ]\n", dev_tbl[i].control_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].control_handle;
dev_types[i].dev_type = CONTROL;
}
}
Why not change the prototypes to something like:
void load_resources(int*)
(they're not actually returning anything) then, in your main code, have:
int base = 0;
load_resources (&base);
load_networks (&base);
load_controls (&base);
Each function is then responsible for using and updating *base like this:
void load_resources (int *pBase) {
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++, (*pBase)++) { // <-- see here!
dev_tbl[i].resource_handle = get_resources();
printf("dev_tbl[i].resource_handle [ %d ]\n", dev_tbl[i].resource_handle);
dev_types[*pBase].id = i;
dev_types[*pBase].dev_handle = dev_tbl[i].resource_handle;
dev_types[*pBase].dev_type = RESOURCE;
}
}
One option is to have each of your functions take the base index as a parameter, and returning the first available index:
int index = 0;
index = load_resources(index);
index = load_network(index);
// and so on
With this yout functions would look something like this:
int load_resources(int base_index)
{
size_t i = 0;
size_t index;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
index = base_index + i;
dev_tbl[index].resource_handle = get_resources();
//
}
return index + 1;
}
By the way, your functions do have int return types, but do not return anything.
Hold a pointer or index variable within the structure itself. It's an indicator for how far the structure has been filled up generally.
There are only two ways to persist data from one scope to the next - on the stack and on the heap. Since you have already ruled out any global variables here, that would require you to use stack variables, by passing in a parameter and returning a value, or passing in a pointer to a parameter.