EmbeddedRelated.com
The 2024 Embedded Online Conference

Incremental Encoder Decode Trick

David January 16, 20131 comment Coded in C
// Incremental encoder decoding.
uint new;
uint old;
bool direction; 
int count=0;

/* Get the latest 2bit sample. */
new = get_new_bits();  // Your function to get new samples.

/* XOR the lower bit from the new sample with the upper bit from the old.*/
direction = (new&1) ^ (old>>1)

/* The "direction" var holds the direction of rotation. */

/* Transfer the new sample to the old sample. */
old = new;

/* We can use this to inc or dec a counter to maintain position of rotation. */
if(direction) counter--; else counter++;

CRC-16 Calculation

Dr. Maykel Alonso January 16, 20138 comments Coded in C
/***** crc16.h *****/
//Tested
#define CRC16_DNP	0x3D65		// DNP, IEC 870, M-BUS, wM-BUS, ...
#define CRC16_CCITT	0x1021		// X.25, V.41, HDLC FCS, Bluetooth, ...

//Other polynoms not tested
#define CRC16_IBM	0x8005		// ModBus, USB, Bisync, CRC-16, CRC-16-ANSI, ...
#define CRC16_T10_DIF	0x8BB7		// SCSI DIF
#define CRC16_DECT	0x0589		// Cordeless Telephones
#define CRC16_ARINC	0xA02B		// ACARS Aplications

#define POLYNOM		CRC16_XXX   // Define the used polynom from one of the aboves

// It calculates the new crc16 with the newByte. Variable crcValue is the actual or initial value (0).
unsigned int crc16(unsigned int crcValue, unsigned char newByte);

/***** crc16.c *****/

#include "crc16.h"

unsigned int crc16(unsigned int crcValue, unsigned char newByte) 
{
	unsigned char i;

	for (i = 0; i < 8; i++) {

		if (((crcValue & 0x8000) >> 8) ^ (newByte & 0x80)){
			crcValue = (crcValue << 1)  ^ POLYNOM;
		}else{
			crcValue = (crcValue << 1);
		}

		newByte <<= 1;
	}
  
	return crcValue;
}

/***** EXAMPLE *****/

unsigned int exampleOfUseCRC16 (unsigned char *Data, usigned char len){

	unsigned int crc;
	unsigned char aux = 0;

	crc = 0x0000; //Initialization of crc to 0x0000 for DNP
	//crc = 0xFFFF; //Initialization of crc to 0xFFFF for CCITT

	while (aux < len){
		crc = crc16(crc,Data[aux]);
		aux++;
	}

	return (~crc); //The crc value for DNP it is obtained by NOT operation

	//return crc; //The crc value for CCITT
}

DS18B20 Interfacing

January 15, 20132 comments Coded in C for the TI MSP430
float get_temp(void);
void reset_18B20(void);
void send_18B20(char data);
unsigned int read_18B20(void);

#define ONE_WIRE_PIN BIT4
#define ONE_WIRE_IN P1IN
#define ONE_WIRE_OUT P1OUT
#define ONE_WIRE_DIR P1DIR

float get_temp(void)
{
    unsigned int temp;
    reset_18B20();
    send_18B20(0xcc);   //send CCH,Skip ROM command
    send_18B20(0x44);
    delay_us(100);

    reset_18B20();
    send_18B20(0xcc);   //send CCH,Skip ROM command
    send_18B20(0xbe);

    temp = read_18B20();
    return((float)temp/8.0);

}

void reset_18B20(void)
{
    ONE_WIRE_DIR |=ONE_WIRE_PIN;
    ONE_WIRE_OUT &= ~ONE_WIRE_PIN;
    __delay_cycles(500);
    ONE_WIRE_OUT |=ONE_WIRE_PIN;
    ONE_WIRE_DIR &= ~ONE_WIRE_PIN;
    __delay_cycles(500);
}

void send_18B20(char data)
{
    char i;

    for(i=8;i>0;i--)
    {
    	ONE_WIRE_DIR |=ONE_WIRE_PIN;
        ONE_WIRE_OUT &= ~ONE_WIRE_PIN;
        __delay_cycles(2);
        if(data & 0x01)
        {
            ONE_WIRE_OUT |= ONE_WIRE_PIN;
        }
        __delay_cycles(60);
        ONE_WIRE_OUT |= ONE_WIRE_PIN;
        ONE_WIRE_DIR &= ~ONE_WIRE_PIN;
        data >>=1;
    }
}

unsigned int read_18B20()
{
    char i;
    unsigned int data=0;

    for(i=16;i>0;i--)
    {
    	ONE_WIRE_DIR |= ONE_WIRE_PIN;
        ONE_WIRE_OUT &= ~ONE_WIRE_PIN;
        __delay_cycles(2);
        ONE_WIRE_OUT |=ONE_WIRE_PIN;
        ONE_WIRE_DIR &= ~ONE_WIRE_PIN;
        __delay_cycles(8);
        if(ONE_WIRE_IN & ONE_WIRE_PIN)
        {
            data |=0x8000;
        }
        data>>=1;
        __delay_cycles(120);
    }
    return(data);
}

Sine Wave Generator

Sathyanarayana Hadadi January 15, 20132 comments Coded in C
/*************************************************************************************************************
sineWaveGeneration
*************************************************************************************************************/
void sineWaveGeneration(unsigned long amplitude, unsigned long frequency, unsigned long time)
{
    const double angularfrequency = (2.0 * pi) * (double)frequency;
    const double pi = 3.141592654;
    double timeperiod;
    const double samplingrate = 48000;
    double displacement;

    //declare values
    
    //obtain omega(the angular frequency)
        // creates a 'for' loop that continues until 'endtime'
    for (timeperiod = 0; timeperiod <= (double)time; timeperiod = timeperiod+(1/samplingrate))
    {
        //creates the sine wave A*sin(wt) by plotting every sample.
        displacement = sin(angularfrequency * timeperiod) * amplitude;
    }
    return;
}

Circular FIFO Buffer

Dr. Maykel Alonso January 15, 20137 comments Coded in C
/***** circularBuffer.h *****/

#ifndef CIRCULAR_BUFFER_H_
#define CIRCULAR_BUFFER_H_

#define BUFFER_SIZE 128
#define TYPE char

// Check if the buffer it is full
bool isFull();

// Check if the buffer it is empty	
bool isEmpty();

// Get the first element from the FIFO queue
TYPE getElement();

// Add an element to the FIFO queue
bool addElement(TYPE data);

// Return the number of Elements that are in the FIFO queue
unsigned char getNumberOfElements();

#endif /*CIRCULAR_BUFFER_H_*/

/***** circularBuffer.cpp *****/

#include "circularBuffer.h"

TYPE Buffer[BUFFER_SIZE + 1]; // It needs 1 extra byte to difference full and empty
unsigned char next = 0;
unsigned char first = 0;

bool isFull(){
	if (getNumberOfElements() == BUFFER_SIZE){
		return true;
	}else{
		return false;
	}
}
	
bool isEmpty(){
	if ( next == first ){
		return true;
	}else{
		return false;
	}	
}
	
TYPE getElement(){
	TYPE theElement = 0;
	if (! isEmpty()){	 
		theElement =  Buffer[first];	
		if ( first != BUFFER_SIZE ){
			first++;
		}else{
			first = 0;
		}		
	}

	return theElement;// Return 0 always if it is empty, must be checked before
}

bool addElement(TYPE data){	
	if (!isFull()){
		 Buffer[next] = data;
		 if ( next != BUFFER_SIZE ){
			next++;
		 }else{
			 next = 0;
		 }
		return true;
	}else{
		return false;
	}	
}

unsigned char getNumberOfElements(){	
	if (next >= first){
		return (next - first);
	}else{
		return (BUFFER_SIZE - next + first);
	}	
}

The 2024 Embedded Online Conference