expected expression before '!=' token... Where I'm wrong? - c

enum LIVELLI_EMERGENZA {
LIV_EME_UNO = 0x0001,
LIV_EME_DUE = 0x0002,
LIV_EME_TRE = 0x0003
};
typedef struct Emergenza {
int Tipo;
short Livello;
} Emergenza;
void TrovaEmergenze()
{
if(INPUT_GET(IN_FUNGO_EMERGENZA)) {
Emergenza.Tipo |= EME_FUNGO_PREMUTO;
Emergenza.Livello |= LIV_EME_UNO;
}
if((INPUT_GET(IN_FC_CARTER_LAMA))){
Emergenza.Tipo |= EME_CARTER_LAMA_APERTO;
Emergenza.Livello |= LIV_EME_DUE;
}
}
char EmeLivello1()
{
if((Emergenza.Livello & LIV_EME_UNO) != 0)
return 1;
return 0;
}
Having evaluated the mask emergenza.livello I'm going to check it with & LIV_EME_UNO. If it is different from 0, this means that the bits in the mask is high; but I get the error "expected expression before '!=' token".

In your code, Emergenza is essentially a datatype, not a variable. You need to have a variable of that type to use the member access operator .
To make Emergenza a variable instead of a datatype do this:
struct Emergenza {
int Tipo;
short Livello;
} Emergenza;
In summary, remove the typedef.

Related

Can I access my union using the arrow operator (->)?

I would like to know whether or not I can use the arrow operator in my union and I don't have access to my build environment.
Let's say that I have the following union
union max30205_raw_data {
struct {
uint8_t lsb;
uint8_t msb;
};
struct {
uint16_t magnitude_bits:15;
uint16_t sign_bit:1;
};
uint16_t uwrd;
int16_t swrd;
};
I will fill the content of the union in the following way, but I was wondering whether the access to the union member msb and lsb is correct?
int32_t max30205_read_reg16_WithDefUnion(char reg, max30205_raw_data *p_unionRawData) {
char aux[] = {0,0}
int32_t error;
if (reg == MAX30205_REG_TEMPERATURE || reg == MAX30205_REG_THYST_LOW_TRIP || reg == MAX30205_REG_TOS_HIGH_TRIP) {
error = twi_max30205_read(&myMax30205Instance,max30205Address,reg,&aux,sizeof(aux));
if(error == 0){
p_unionRawData->msb = aux[0];//IS THIS RIGHT IN C?
p_unionRawData->lsb = aux[1];//IS THIS RIGHT IN C?
}
}
return error;
}
I will call max30205_read_reg16_WithDefUnion()as
int16_t max30205MeasureTemperatureWithDefUnion(void) {
char regT = MAX30205_REG_TEMPERATURE;
max30205_raw_data rawTemp;
rawTemp.msb = 0;
rawTemp.lsb = 0;
rawTemp.swrd = 0;
int16_t temperatureValue = 0;
if (max30205_read_reg16_WithDefUnion(regT,&rawTemp) ==0)
temperatureValue = rawTemp.swrd;
return temperatureValue;
}
Yes. -> works with both pointers to structs and pointers to unions.

Why am I getting a type error when trying to use a struct from a header in my .c file?

I really don't understand what is happening here. I'm trying to access members of a struct in a .c file, but it's giving an 'error-type' when I try to access the struct variable. Anybody have any idea what's going on here?
CPU.h Header file:
#ifndef _CPU_H
#define _CPU_H
#include <stdint.h>
typedef struct cpu_registers
{
union
{
struct
{
uint8_t f;
uint8_t a;
};
uint16_t af;
};
union
{
struct
{
uint8_t c;
uint8_t b;
};
uint16_t bc;
};
} cpu_registers;
#endif /* _CPU_H */
CPU.c file:
#include "CPU.h"
cpu_registers regs;
regs.af = 0xFFFF;
Here are the errors upon compilation with clang:
CPU.c:4:1: error: unknown type name 'regs'
regs.af = 0xFFFF;
^
CPU.c:4:5: error: expected identifier or '('
regs.af = 0xFFFF;
^
2 errors generated.
You can declare and initialize global variables outside of functions, but you cannot do anything else with them.
So, you could do this:
cpu_registers regs = { .af = 0xFFFF };
However, do note that this will not work:
int val = 0xFFFF;
cpu_registers regs = { .af = val };
And - maybe a bit surprisingly - not this either:
const int val = 0xFFFF;
cpu_registers regs = { .af = val };

adding two structs representing different types together

I have a struct like so:
typedef enum any_type{
ANY_TYPE_CHAR,
ANY_TYPE_UCHAR,
ANY_TYPE_SHORT,
ANY_TYPE_USHORT,
ANY_TYPE_INT,
ANY_TYPE_UINT,
ANY_TYPE_LONG,
ANY_TYPE_ULONG,
ANY_TYPE_FLOAT,
ANY_TYPE_DOUBLE,
} any_type;
typedef struct any{
any_type type;
union{
char as_char;
unsigned char as_uchar;
short as_short;
unsigned short as_ushort;
int as_int;
unsigned int as_uint;
long as_long;
unsigned long as_ulong;
float as_float;
double as_double;
};
} any;
which represents a variable which is one of the types specified. There are four possible operations on these structs, which are addition, subtraction, multiplication and division.
My question is, is there an efficient way to do these operations on them without doing lots of if statements for every case? That would result in 4 * 10 * 10 = 400 if/else if statements for these four operations alone, which is certainly not efficient!
My code is in C
Thanks in advance.
To avoid a combinational nightmare, consider that there are 3 groups of types, unsigned integers, signed integers, floating point.
A goal is to determine which of the 3 groups the operation is to use. Then get the value of the operand per its type and the target group. Do the math per that group. Then save per the group and the highest ranking type.
For each of the 10 types, create 10 functions to fetch the data and return as the widest unsigned integer. Another 10 for signed integer and lastly 10 for floating point.
For each for the 10 types, do the same to create functions to set the data. So far 60 small functions.
To access the correct function, use a table look up in a function. 3 more functions for getting, 3 more for setting.
An example addition function is at the end. It looks for the highest ranking type and gets/adds/sets based on the one of 3 groups.
Now add 3 more functions for -,/,*. Total about 60 + 6 + 4 functions.
Bonus: To add a new function like %, only takes 1 more function to write.
#include<assert.h>
typedef enum any_type{
// Insure these are in rank order
// ANY_TYPE_CHAR left out for now
ANY_TYPE_SCHAR,
ANY_TYPE_UCHAR,
ANY_TYPE_SHORT,
ANY_TYPE_USHORT,
ANY_TYPE_INT,
ANY_TYPE_UINT,
ANY_TYPE_LONG,
ANY_TYPE_ULONG,
ANY_TYPE_FLOAT,
ANY_TYPE_DOUBLE,
ANY_TYPE_N,
} any_type;
typedef struct any{
any_type type;
union{
signed char as_schar;
unsigned char as_uchar;
short as_short;
unsigned short as_ushort;
int as_int;
unsigned int as_uint;
long as_long;
unsigned long as_ulong;
float as_float;
double as_double;
};
} any;
/////////////////////////////////////
unsigned long any_uget_schar(const any *x) {
return (unsigned long) x->as_schar;
}
unsigned long any_uget_uchar(const any *x) {
return x->as_uchar;
}
/* 8 more */
unsigned long any_get_unsigned(const any *x) {
static unsigned long (*uget[ANY_TYPE_N])(const any *x) = {
any_uget_schar, any_uget_uchar, /* 8 others */ };
assert(x->type < ANY_TYPE_N);
return (uget[x->type])(x);
}
/////////////////////////////////////
signed long any_sget_schar(const any *x) {
return x->as_schar;
}
signed long any_sget_uchar(const any *x) {
return x->as_uchar;
}
/* 8 more */
signed long any_get_signed(const any *x) {
static signed long (*sget[ANY_TYPE_N])(const any *x) = {
any_sget_schar, any_sget_uchar, /* 8 others */ };
assert(x->type < ANY_TYPE_N);
return sget[x->type](x);
}
/////////////////////////////////////
double any_get_fp(const any *x); // similar for floating point
/////////////////////////////////////
void any_uset_schar(any *x, unsigned long y) {
x->as_schar = (signed char) y;
}
void any_uset_uchar(any *x, unsigned long y) {
x->as_uchar = (unsigned char) y;
}
/* 8 more */
void any_set_unsigned(any *x, unsigned long y) {
static void (*uset[ANY_TYPE_N])(any *x, unsigned long y) = {
any_uset_schar, any_uset_uchar, /* 8 others */ };
assert(x->type < ANY_TYPE_N);
uset[x->type](x,y);
}
/* 10 more for any_sset_... */
/* 10 more for any_fset_... */
///////////////////////////////////////////////
static const char classify[] = "susususuff";
any any_get_add(any a, any b) {
any sum;
sum.type = max(a.type, b.type);
assert(sum.type < ANY_TYPE_N);
switch (classify[sum.type]) {
case 's':
any_set_signed(&sum, any_get_signed(&a) + any_get_signed(&b));
break;
case 'u':
any_set_unsigned(&sum, any_get_unsigned(&a) + any_get_unsigned(&b));
break;
case 'f':
any_set_fp(&sum, any_get_signed(&a) + any_get_signed(&b));
break;
default:
assert(0);
}
return sum;
}
This is going to require a lot of code, because combinatorial explosion is part of the problem.
Use a table-driven approach: define two tables, one for converting between types, and one for performing operations on them.
For conversion make a function pointer type
typedef any (*convert_any)(any val, any_type target);
and make a table of conversions keyed on any_type:
convert_any conversion[] = {
convert_char,
convert_uchar,
convert_short,
...
};
with implementations like this for each type (you'll need ten of these):
static any convert_char(any val, any_type target) {
any res = { .type = target };
switch (target) {
case ANY_TYPE_CHAR: res.as_char = val.as_char; break;
case ANY_TYPE_INT: res.as_int = (int)val.as_char; break;
...
}
return res;
}
For operations make another function pointer type:
typedef any (*operation_any)(any left, any right);
You will need to make a 3D array of such pointers - one for each triple of operation, the type of its left operand, and the type of its right operand.
Implementations would look like this:
static any add_int(any left, any right) {
any lhs = conversion[left.type](left, ANY_TYPE_INT);
any rhs = conversion[right.type](right, ANY_TYPE_INT);
any res {.type = ANY_TYPE_INT, .as_int = lhs.as_int + rhs.as_int};
return res;
}
static any add_double(any left, any right) {
any lhs = conversion[left.type](left, ANY_TYPE_DOUBLE);
any rhs = conversion[right.type](right, ANY_TYPE_DOUBLE);
any res {.type = ANY_TYPE_DOUBLE, .as_double = lhs.as_double + rhs.as_double };
return res;
}
There will be forty such implementations - one for each result type and operation pair. The 3D table will contain 400 entries, depending on the type of the result the operation needs to produce. The call will look up into 3D array, find operation_any pointer, pass two arguments, and get a result like this:
any res = operations[PLUS_OP][left.type][right.type](left, right);
You should make expr structure. This mean one node of AST (Abstruct Syntax Tree). And it have op. This mean +,-,*,/ for the lhs, rhs. do_expr caluculate expression. Finally, dump_any print the value.
#include <stdio.h>
#include <assert.h>
typedef enum any_type{
ANY_TYPE_CHAR,
ANY_TYPE_UCHAR,
ANY_TYPE_SHORT,
ANY_TYPE_USHORT,
ANY_TYPE_INT,
ANY_TYPE_UINT,
ANY_TYPE_LONG,
ANY_TYPE_ULONG,
ANY_TYPE_FLOAT,
ANY_TYPE_DOUBLE,
} any_type;
typedef struct any{
any_type type;
union{
char as_char;
unsigned char as_uchar;
short as_short;
unsigned short as_ushort;
int as_int;
unsigned int as_uint;
long as_long;
unsigned long as_ulong;
float as_float;
double as_double;
};
} any;
typedef enum op_type{
OP_PLUS,
OP_MINUS,
OP_MULT,
OP_DIVID,
} op_type;
typedef struct {
int op;
any lhs;
any rhs;
} expr;
int
do_expr(expr* e, any *r) {
switch (e->op) {
case OP_PLUS:
r->type = e->lhs.type;
r->as_int = e->lhs.as_int + e->rhs.as_int;
return 0;
break;
default:
fprintf(stderr, "unknown operation\n");
break;
}
return 1;
}
void
dump_any(any* a) {
switch (a->type) {
case ANY_TYPE_INT:
printf("%d\n", a->as_int);
break;
default:
assert(!"unknown type");
break;
}
}
int
main(int argc, char* argv[]) {
expr e1 = {
.op = OP_PLUS,
.lhs = { .type = ANY_TYPE_INT, as_int: 1, },
.rhs = { .type = ANY_TYPE_INT, as_int: 2, },
};
any ret;
if (do_expr(&e1, &ret) == 0) {
dump_any(&ret);
}
return 0;
}
Sorry, but you have to do case switching since the compiler has to generate different CPU instructions for different types. The kind of operation is defined by the choice of the variable.

"Grouping" enum values in C

If I had some enums like
typedef enum {
AN_TRISTATE_0,
AN_TRISTATE_1,
AN_NOTHING,
AN_MOTOR_1,
AN_MOTOR_2,
AN_MOTOR_3,
AN_SENSOR_1,
AN_SENSOR_2,
AN_SENSOR_3,
AN_SENSOR_4,
AN_SENSOR_5
} adc_pin_func_t;
and
adc_pin_func_t a_particular_pin = ...
, would it be possible it check if the pin is part of a particular group, e.g pin is part of AN_MOTOR or part of AN_SENSOR, instead of having to check against each item in each possible group.
Or are there more efficient ways of doing this, other than using enums?
Thanks in advance
You could create masks for each of the groups:
typedef enum {
AN_TRISTATE_0 = 0x00001,
AN_TRISTATE_1 = 0x00002,
AN_TRISTATE_MASK = 0x0000f,
AN_NOTHING = 0x00010, // Should this be 0x00000 ?
AN_MOTOR_1 = 0x00100,
AN_MOTOR_2 = 0x00200,
AN_MOTOR_3 = 0x00400,
AN_MOTOR_MASK = 0x00f00,
AN_SENSOR_1 = 0x01000,
AN_SENSOR_2 = 0x02000,
AN_SENSOR_3 = 0x04000,
AN_SENSOR_4 = 0x08000,
AN_SENSOR_5 = 0x10000,
AN_SENSOR_MASK = 0xff000
} adc_pin_func_t;
And then simply test a group against the mask using the & operator:
if (a_particular_pin & AN_SENSOR_MASK)
{
// it's a sensor pin
}
else if (a_particular_pin & AN_MOTOR_MASK)
{
// it's a motor pin
}
EDIT: As others have suggested using a range, then you could probably create a macro for the test, which would allow you to change how the test is performed without the need to change the code (always a good thing):
#define IS_AN_SENSOR(x) (((x) & AN_SENSOR_MASK) != 0)
#define IS_AN_MOTOR(x) (((x) & AN_MOTOR_MASK) != 0)
// etc.
and then the test becomes:
if (IS_AN_SENSOR(a_particular_pin))
{
// it's a sensor pin
}
else if (IS_AN_MOTOR(a_particular_pin))
{
// it's a motor pin
}
// etc
If you then needed to change to using a range then only the macros need to change (and you'd obviously need to define the range min/max):
#define IS_AN_SENSOR(x) ((x) >= AN_SENSOR_START && (x) <= AN_SENSOR_END)
// etc
You are free to choose your enum values, so you could do something like this
typedef enum {
AN_TRISTATE_0 = 0x0001,
AN_TRISTATE_1 = 0x0002,
AN_NOTHING = 0x0000,
AN_MOTOR_1 = 0x0010,
AN_MOTOR_2 = 0x0020,
AN_MOTOR_3 = 0x0030,
AN_SENSOR_1 = 0x0100,
AN_SENSOR_2 = 0x0200,
AN_SENSOR_3, /*and so on*/
AN_SENSOR_4,
AN_SENSOR_5
} adc_pin_func_t;
Then you can compare bits to check categories. For example, a motor type is the only category that will have non-zero (AN_MOTOR_2 & 0x00F0)
You can do a
typedef enum {
AN_TRISTATE_START,
AN_TRISTATE_0 = AN_TRISTATE_START,
AN_TRISTATE_1,
AN_TRISTATE_END = AN_TRISTATE_1,
AN_NOTHING,
AN_MOTOR_START,
AN_MOTOR_1 = AN_MOTOR_START,
AN_MOTOR_2,
AN_MOTOR_3,
AN_MOTOR_END = AN_MOTOR_3,
AN_SENSOR_START,
AN_SENSOR_1 = AN_SENSOR_START,
AN_SENSOR_2,
AN_SENSOR_3,
AN_SENSOR_4,
AN_SENSOR_5,
AN_SENSOR_END = AN_SENSOR_5
} adc_pin_func_t;
bool inline
is_sensor(int pin)
{
return AN_SENSOR_START <= pin
&& pin <= AN_SENSOR_END
}
and then in your code
if ( is_sensor(pin) )
{
/* body */
}
This way you don't have to care about masking particular values. May be useful if groups contain a lot of values.
You can give values to the enum in exponents of 2. Then you can simply use bitwise AND and OR masks. So you can assign values like 1,2,4,8,16,32... so on.
typedef enum {
AN_TRISTATE_0 = 1,
AN_TRISTATE_1 = 2,
AN_NOTHING = 4,
AN_MOTOR_1 = 8,
AN_MOTOR_2 = 16,
AN_MOTOR_3 = 32,
AN_SENSOR_1 = 64,
AN_SENSOR_2 = 128,
AN_SENSOR_3 = 256,
AN_SENSOR_4 = 512,
AN_SENSOR_5 = 1024
} adc_pin_func_t;
Then for checking with motor type, you can AND with (32+16+8) = 56. So pin & 56, if non zero will mean it is of motor type.
If you really like to have some modularity in your enum (the "hard coded" enum values are also a valid method), you can implement a struct with some OOP flavour. The design become more complicated, but the usage is still simple :
#include <stdio.h>
#include <string.h>
// Every enum will have its first value start at the value of the previous enum's last member PLUS ONE
#define OFFSET_ENUM_MOTOR ( sizeof(adc_pin_tristate_t) )
#define OFFSET_ENUM_SENSOR ( OFFSET_ENUM_MOTOR + sizeof(adc_pin_motor_t) )
///////////////////////////////////////////////////////////////////////////////
// Enum
typedef enum {
AN_TRISTATE_0,
AN_TRISTATE_1,
AN_NOTHING
} adc_pin_tristate_t;
typedef enum {
AN_MOTOR_1 = OFFSET_ENUM_MOTOR,
AN_MOTOR_2,
AN_MOTOR_3
} adc_pin_motor_t;
typedef enum {
AN_SENSOR_1 = OFFSET_ENUM_SENSOR,
AN_SENSOR_2,
AN_SENSOR_3,
AN_SENSOR_4,
AN_SENSOR_5
} adc_pin_sensor_t;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Struct for abstraction
typedef struct adc_pin_func2_t{
// our "enum value"
unsigned int enum_id;
// return is the enum is a motor one
int(*isMotor)(struct adc_pin_func2_t*);
} adc_pin_func2_t;
// Struct
///////////////////////////////////////////////////////////////////////////////
// Member methods : return if the enum is a motor one
int
PinFunc_isMotor(
adc_pin_func2_t *This /* object */
)
{
return ( (This->enum_id>=OFFSET_ENUM_MOTOR) && (This->enum_id<OFFSET_ENUM_SENSOR) );
}
// Creation of the structure
// Initialization
static void
PinFunc_Init(
adc_pin_func2_t *This, /* output */
unsigned int identifier /* old enum identifier */
)
{
// copy members
This->enum_id = identifier;
//copy methods (do not forget to do it !)
This->isMotor = PinFunc_isMotor;
}
// Constructor
adc_pin_func2_t
PinFunc_Create(
unsigned int identifier /* old enum identifier */
)
{
adc_pin_func2_t This;
PinFunc_Init(&This, identifier);
return This;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
main()
{
adc_pin_func2_t pin = PinFunc_Create(AN_NOTHING);
printf("%d \n", pin );
printf("%d \n", pin.isMotor(&pin) );
adc_pin_func2_t pin2 = PinFunc_Create(AN_MOTOR_2);
printf("%d \n", pin2 );
printf("%d \n", pin2.isMotor(&pin2) );
}
The usage of members functions like pin.isMotor(&pin) isn't very elegant (we repeat pin), but it is a shortcoming of C, which is not an OOP language.
If you don't want to have to manually maintain non-overlapping values, then you can very nearly get it all handled for you automatically. The only thing you'll have to figure out is the maximum number of bits in a group:
#define PIN_GROUP_SHIFT 4
#define GET_PIN_GROUP(x) (adc_pin_group_t)((y) >> PIN_GROUP_SHIFT)
#define PIN_GROUP_START(x) XX_GROUP_##x = ((GROUP_##x << PIN_GROUP_SHIFT) - 1),
enum {
GROUP_TRISTATE,
GROUP_NOTHING,
GROUP_MOTOR,
GROUP_SENSOR
} adc_pin_group_t;
typedef enum {
PIN_GROUP_START(TRISTATE)
AN_TRISTATE_0,
AN_TRISTATE_1,
PIN_GROUP_START(NOTHING)
AN_NOTHING,
PIN_GROUP_START(MOTOR)
AN_MOTOR_1,
AN_MOTOR_2,
AN_MOTOR_3,
PIN_GROUP_START(SENSOR)
AN_SENSOR_1,
AN_SENSOR_2,
AN_SENSOR_3,
AN_SENSOR_4,
AN_SENSOR_5
} adc_pin_func_t;
To determine the type of an entry in the enum, use GET_PIN_GROUP(x), and compare it to whichever value of the adc_pin_group_t enum. You can even switch on the result, if that's helpful.
However, that AN_NOTHING entry makes me wonder if your enum is meant to line up with specific values for each entry. are specific values associated with the pins, which you may not be able to assign arbitrarily. In that case you might need to try something complicated (which I haven't tested):
#define GET_PIN_VALUE(x) ((x) & ((1 << PIN_GROUP_SHIFT) - 1)
#define PIN_GROUP_START(x) \
WW_GROUP_##x, \
XX_GROUP_##x = (GROUP_##x << PIN_GROUP_SHIFT) \
+ GET_PIN_INDEX(WW_GROUP_##x) - 1,
Where you need to know the value that your original enum would have used, use GET_PIN_INDEX(x).

Struct initialization problem in C

I seem to be having a problem setting the values of an array inside a structure with a meaningless error spat out of the compiler:
expected primary-expression before '{' token
I understand that a structure must "exist" to accept values, and it exists as a pointer to one. I would like you to explain to me what i am doing wrong and how to achieve my objective.
struct EventCheckData {
unsigned long refresh_time;
unsigned long last_execution_ms; //Can also serve to delay at startup
byte signal_type;
};
struct ClockData {
struct EventCheckData event_array[4];
byte event_count;
unsigned long last_absolute_time;
UISignal *warning_signals;
};
void ResetClock(UISignal *warning_signal, struct ClockData *clock_data, unsigned long absolute_time) {
if(SignalCheckValue(warning_signal, RESET_CLOCK, 1)) {
extern volatile unsigned long timer0_overflow_count;
timer0_overflow_count = 0;
clock_data->last_absolute_time = absolute_time;
clock_data->event_count = 3;
(clock_data->event_array)[0] = { .refresh_time = 3000UL, .last_execution_ms = 0UL, .signal_type = WATER_PUMP_ON};
// clock_data->event_array[1] = {10000UL, 0UL, EXPORT_LOG};
// clock_data->event_array[2] = {100000UL, 0UL, EXTERNAL_CONNECTION};
SignalSet(warning_signal, RESET_CLOCK, 0);
}
}
Thank you
Paulo Neves
(clock_data->event_array)[0] = { .refresh_time = 3000UL, .last_execution_ms = 0UL, .signal_type = WATER_PUMP_ON}; is not initialization. It is assignment.
And you cannot use initializer syntax in assignment.
With C99, you should be able to use a compound literal, like
(clock_data->event_array)[0] = (struct EventCheckData){ .refresh_time = 3000UL, .last_execution_ms = 0UL, .signal_type = WATER_PUMP_ON};
The way you are assigning it looks like an initializer. You need assignment, try a compound literal:
clock_data->event_array[0] = (struct EventCheckData){ .refresh_time = 3000UL, ...};
Without any C99 stuff you can simply use:
void ResetClock(UISignal *warning_signal, struct ClockData *clock_data, unsigned long absolute_time) {
if(SignalCheckValue(warning_signal, RESET_CLOCK, 1)) {
extern volatile unsigned long timer0_overflow_count;
timer0_overflow_count = 0;
clock_data->last_absolute_time = absolute_time;
clock_data->event_count = 3;
{
struct EventCheckData a[]={ {3000UL, 0UL, WATER_PUMP_ON},
{10000UL, 0UL, EXPORT_LOG},
{100000UL, 0UL, EXTERNAL_CONNECTION}};
memcpy(clock_data->event_array,a,sizeof a);
}
SignalSet(warning_signal, RESET_CLOCK, 0);
}

Resources