Code Snippets Submitted by tgil
Exponential Moving Average
//This macros defines an alpha value between 0 and 1
#define DSP_EMA_I32_ALPHA(x) ( (uint16_t)(x * 65535) )
int32_t dsp_ema_i32(int32_t in, int32_t average, uint16_t alpha){
int64_t tmp0; //calcs must be done in 64-bit math to avoid overflow
tmp0 = (int64_t)in * (alpha) + (int64_t)average * (65536 - alpha);
return (int32_t)((tmp0 + 32768) / 65536); //scale back to 32-bit (with rounding)
}
//here is a function that uses the averaging code
int32_t my_avg_func(void){
static int32_t average = 0;
int32_t adc_value;
adc_value = read_the_adc_value();
average = dsp_ema_i32(adc_value, average, DSP_EMA_I32_ALPHA(0.1));
return average;
}
base64 Encoding
#include <string.h>
#include <stdint.h>
//This is a helper function to convert a six-bit value to base64
char base64_encode_six(uint8_t six_bit_value){
uint8_t x;
char c;
x = six_bit_value & ~0xC0; //remove top two bits (should be zero anyway)
if( x < 26 ){
c = 'A' + x;
} else if ( x < 52 ){
c = 'a' + (x - 26);
} else if( x < 62 ){
c = '0' + (x - 52);
} else if( x == 62 ){
c = '+';
} else if (x == 63 ){
c = '/';
} else {
printf("ERROR IN BASE 64\n");
c = 'A';
}
return c;
}
//This is the function for encoding in base64
void base64_encode(char * dest, const char * src){
int bits;
int i;
int j;
int k;
int len;
uint8_t six_bits[4];
len = strlen(src);
k = 0;
//We need to encode three bytes at a time in to four encoded bytes
for(i=0; i < len; i+=3){
//First the thress bytes are broken down into six-bit sections
six_bits[0] = (src[i] >> 2) & 0x3F;
six_bits[1] = ((src[i] << 4) & 0x30) + ((src[i+1]>>4) & 0x0F);
six_bits[2] = ((src[i+1] << 2) & 0x3C) + ((src[i+2]>>6) & 0x03);
six_bits[3] = src[i+2] & 0x3F;
//now we use the helper function to convert from six-bits to base64
for(j=0; j < 4; j++){
dest[k+j] = base64_encode_six(six_bits[j]);
}
k+=4;
}
//at the end, we add = if the input is not divisible by 3
if( (len % 3) == 1 ){
//two equals at end
dest[k-2] = '=';
dest[k-1] = '=';
} else if ( (len %3 ) == 2 ){
dest[k-1] = '=';
}
//finally, zero terminate the output string
dest[k] = 0;
}
PID (Floating Point)
/*! \details This structure holds the data to run a
* floating point PID loop.
*/
typedef struct{
float max /*! \brief Max manipulated value */;
float min /*! \brief Miniumum manipulated value */;
float e /*! \brief Error value */;
float i /*! \brief Integrator value */;
float kp /*! \brief Proportional constant */;
float ki /*! \brief Integrator constant */;
float kd /*! \brief Differential constant */;
} pid_f_t;
/*! \details This function initializes the data in a PID structure.
*
*/
void pid_init_f(pid_f_t * ptr /*! A pointer to the PID data structure */,
float min /*! The manipulated variable's minimum value */,
float max /*! The manipulated variable's maximum value */){
memset(ptr, 0, sizeof(pid_f_t));
ptr->min = min;
ptr->max = max;
}
/*! \details This function updates the value of the manipulated variable (MV)
* based on the current state of the PID loop.
*/
float pid_update_f(float sp /*! The set point */,
float pv /*! The process variable */,
pid_f_t * ptr /*! A pointer to the PID constants */){
float temp;
float e;
float p;
float manp;
float tmpi;
//get the error from the last call
e = ptr->e;
//calculate the new error (set point - present value)
ptr->e = sp - pv;
//use a temp variable for the integrator
tmpi = ptr->i + ptr->e;
//update the manipulated process variable
manp = ptr->kp * ptr->e + ptr->ki * tmpi + ptr->kd * (ptr->e - e);
//the integrator is only updated if the manipulated process is within range
//otherwise the system will likely become unstable
if ( (manp < ptr->max) && (manp > ptr->min) ){
ptr->i = tmpi;
} else if ( manp > ptr->max ){
manp = ptr->max;
} else if ( manp < ptr->min ){
manp = ptr->min;
}
return manp;
}
PID (Floating Point)
/*! \details This structure holds the data to run a
* floating point PID loop.
*/
typedef struct{
float max /*! \brief Max manipulated value */;
float min /*! \brief Miniumum manipulated value */;
float e /*! \brief Error value */;
float i /*! \brief Integrator value */;
float kp /*! \brief Proportional constant */;
float ki /*! \brief Integrator constant */;
float kd /*! \brief Differential constant */;
} pid_f_t;
/*! \details This function initializes the data in a PID structure.
*
*/
void pid_init_f(pid_f_t * ptr /*! A pointer to the PID data structure */,
float min /*! The manipulated variable's minimum value */,
float max /*! The manipulated variable's maximum value */){
memset(ptr, 0, sizeof(pid_f_t));
ptr->min = min;
ptr->max = max;
}
/*! \details This function updates the value of the manipulated variable (MV)
* based on the current state of the PID loop.
*/
float pid_update_f(float sp /*! The set point */,
float pv /*! The process variable */,
pid_f_t * ptr /*! A pointer to the PID constants */){
float temp;
float e;
float p;
float manp;
float tmpi;
//get the error from the last call
e = ptr->e;
//calculate the new error (set point - present value)
ptr->e = sp - pv;
//use a temp variable for the integrator
tmpi = ptr->i + ptr->e;
//update the manipulated process variable
manp = ptr->kp * ptr->e + ptr->ki * tmpi + ptr->kd * (ptr->e - e);
//the integrator is only updated if the manipulated process is within range
//otherwise the system will likely become unstable
if ( (manp < ptr->max) && (manp > ptr->min) ){
ptr->i = tmpi;
} else if ( manp > ptr->max ){
manp = ptr->max;
} else if ( manp < ptr->min ){
manp = ptr->min;
}
return manp;
}
base64 Encoding
#include <string.h>
#include <stdint.h>
//This is a helper function to convert a six-bit value to base64
char base64_encode_six(uint8_t six_bit_value){
uint8_t x;
char c;
x = six_bit_value & ~0xC0; //remove top two bits (should be zero anyway)
if( x < 26 ){
c = 'A' + x;
} else if ( x < 52 ){
c = 'a' + (x - 26);
} else if( x < 62 ){
c = '0' + (x - 52);
} else if( x == 62 ){
c = '+';
} else if (x == 63 ){
c = '/';
} else {
printf("ERROR IN BASE 64\n");
c = 'A';
}
return c;
}
//This is the function for encoding in base64
void base64_encode(char * dest, const char * src){
int bits;
int i;
int j;
int k;
int len;
uint8_t six_bits[4];
len = strlen(src);
k = 0;
//We need to encode three bytes at a time in to four encoded bytes
for(i=0; i < len; i+=3){
//First the thress bytes are broken down into six-bit sections
six_bits[0] = (src[i] >> 2) & 0x3F;
six_bits[1] = ((src[i] << 4) & 0x30) + ((src[i+1]>>4) & 0x0F);
six_bits[2] = ((src[i+1] << 2) & 0x3C) + ((src[i+2]>>6) & 0x03);
six_bits[3] = src[i+2] & 0x3F;
//now we use the helper function to convert from six-bits to base64
for(j=0; j < 4; j++){
dest[k+j] = base64_encode_six(six_bits[j]);
}
k+=4;
}
//at the end, we add = if the input is not divisible by 3
if( (len % 3) == 1 ){
//two equals at end
dest[k-2] = '=';
dest[k-1] = '=';
} else if ( (len %3 ) == 2 ){
dest[k-1] = '=';
}
//finally, zero terminate the output string
dest[k] = 0;
}
Exponential Moving Average
//This macros defines an alpha value between 0 and 1
#define DSP_EMA_I32_ALPHA(x) ( (uint16_t)(x * 65535) )
int32_t dsp_ema_i32(int32_t in, int32_t average, uint16_t alpha){
int64_t tmp0; //calcs must be done in 64-bit math to avoid overflow
tmp0 = (int64_t)in * (alpha) + (int64_t)average * (65536 - alpha);
return (int32_t)((tmp0 + 32768) / 65536); //scale back to 32-bit (with rounding)
}
//here is a function that uses the averaging code
int32_t my_avg_func(void){
static int32_t average = 0;
int32_t adc_value;
adc_value = read_the_adc_value();
average = dsp_ema_i32(adc_value, average, DSP_EMA_I32_ALPHA(0.1));
return average;
}