Embedded Electronics HW/SW Engineer with expertise in Hardware & Software including PCB design and Analysis, firmware development and Android development apart from causual web-development (wordpress & Laravel) and to some extent photography.
Here I am sharing a header file called easyavr.h. This is a pretty basic header file with some helper functions related to input output pins of AVR
#ifndef __EASYAVR_H_
#define __EASYAVR_H_
// Sets pin of port to 1
//
// Example for PD2: PIN_ON(PORTD, 2)
#define PIN_ON(port,pin) ((port) |= (1 << (pin)))
// Sets pin of port to 0
//
// Example for PD2: PIN_OFF(PORTD, 2)
#define PIN_OFF(port,pin) ((port) &= ~(1 << (pin)))
// Sets pin of port to value
//
// Example for PD2: PIN_SET(PORTD, 2, 1)
#define PIN_SET(port,pin,val) (((val) > 0) ? PIN_ON((port),(pin)) : PIN_OFF((port),(pin)))
// Sets all of port pins to OUTPUT mode
//
// Example for PORTD: PORT_AS_OUTPUT(PORTD)
#define PORT_AS_OUTPUT(port) ((port) = 0xFF)
// Sets all of port pins to INPUT mode
//
// Example for PORTD: PORT_AS_INPUT(PORTD)
#define PORT_AS_INPUT(port) ((port) = 0x00)
// Sets pin of port to OUTPUT mode
//
// Example for PD1: PORT_AS_OUTPUT(DDRD, 1)
#define PIN_AS_OUTPUT(ddr,pin) ((ddr) |= (1 << (pin)))
// Sets pin of port to INPUT mode
//
// Example for PD1: PORT_AS_INPUT(DDRD, 1)
#define PIN_AS_INPUT(ddr,pin) ((ddr) &= ~(1 << (pin)))
// Checks pin's value of port
// Returns 1 or 0
//
// Example for PD2: CHECK_PIN(PIND, 2)
#define CHECK_PIN(pinreg,pin) (((pinreg) & (1 << (pin))) != 0)
#endif
Wanted to share this snippet of code which I used to display a decimal numbers binary representation. It is quite self explanatory and easy to understand.
/**
* Turns a decimal value to its binary representation
*/
char* dec2binWzerofill(unsigned long Dec, unsigned int bitLength){
return dec2binWcharfill(Dec, bitLength, '0');
}
char* dec2binWcharfill(unsigned long Dec, unsigned int bitLength, char fill){
static char bin[64];
unsigned int i=0;
unsigned int j;
while (Dec > 0) {
bin[32+i++] = ((Dec & 1) > 0) ? '1' : fill;
Dec = Dec >> 1;
}
for ( j = 0; j< bitLength; j++) {
if (j >= bitLength - i) {
bin[j] = bin[ 31 + i - (j - (bitLength - i)) ];
}else {
bin[j] = fill;
}
}
bin[bitLength] = ' ';
return bin;
}
Need to measure water quality and other parameters? DF Robot’s Analog pH Meter Kit is specially designed for simple interface and has convenient and practical connector and a bunch of features. Get pH measurements at ± 0.1pH (25 ℃). For most hobbyist this great accuracy range and it’s low cost makes this a great tool for biorobotics and other projects! It has an LED which works as the Power Indicator, a BNC connector and PH2.0 sensor interface. To use it, just connect the pH sensor with BND connector, and plug the PH2.0 interface into the analog input port of any micro-controller.
The Wiki page has a sample code for using this kit with arduino, along with schematic, specifications, features ,precautions and setup Instructions. The arduino Interfacing is simple and the schematic and code is available on the wiki page.
Interfacing with a pic is also straight forward, Shawon Shahryiar shared his project where he used a PIC16F684. Below is the demonstration video and code.
AVRWIZ is a code generator for the popular Atmel AVR microcontrollers, optimized for the AVR Studio IDE. Its a very nice automatic code generator for AVR microcontrollers developed by tcg in avrfreaks, which can generate code for most common tasks. It support baud calculator, timer calculator, multitasking generator, interrupts, ports and more. But there are several thing to be done like TWI, USI. As Author states there is lots of testing to be done. Project is open for new ideas and suggestions.
Nice thing I like about it that program is capable to generate code instantly. It can be saved as single file or whole Avr Studio project with makefile which is ready to compile instantly.
In case you have a string data which has some non ASCII characters and want to strip off all those non-ASCII characters the following regular expression will help you.
[^u0000-u007F]+
Explanation
[^u0000-u007F]+ match a single character not present in the list below
Quantifier:+ Between one and unlimited times, as many times as possible
u0000-u007F a single character in the range between the following two characters
u0000 the literal character u0000 (case sensitive)
u007F the literal character u007F (case sensitive)
^ is the not operator. It tells the regex to find everything that doesn’t match, instead of everything that does match.
The u####-u#### says which characters match.u0000-u007F is the equivilent of the first 255 characters in utf-8 or unicode, which are always the ASCII characters. So you match every non ASCII character (because of the not)
I was working on a code for a module on my GSM gateway today , for which I had given 1 pin of micro-controller to use as software Tx. Software UARTs usually uses timers to make them robust, but I had already used them all. So I decided to write a code using software delays.
The UART logic is inverted , so to send logic 1 you have to send low signal and vice versa . Here is my code , hope it might help someone else.
/*
* soft-uart Tx only without any timmer uses software delays
* the baud rate depends on the delay in us , here I am using
* 4800 with a 1 start bit, 8 databits and 1 stop bit
* if you wanna change the baud rate calculate it by 1/baud and
* modify the _delay_us();
*
* Created: 11/21/2012 1:52:37 PM
* Author: AbuUmar
*/
#include <avr/io.h>
#include <util/delay.h>
#define portlow PORTC&=~0x01
#define porthigh PORTC|=0x01
void putchar_soft(char data_soft)
{
char bit_count=10; // 1+8+1SB
data_soft=~data_soft;
char secc=1;char0:
if (secc=1)
portlow;
else
porthigh;
_delay_us(208);
//_delay_us(208);
for ( char i = 0; i < 8; i++ ) {
if(data_soft & 1)
portlow;
else
porthigh;
data_soft=data_soft>>1;
_delay_us(208);
}
porthigh;
_delay_us(208);
_delay_us(208);
return;
}
int main(void)
{
DDRC|=0b00000001;
porthigh;
char inte=0;
while(1)
{
// example use, initializing a var to 0 and sending the data
// with 1 sec delays
putchar_soft(inte) ;
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
inte++;
}
}
EEPROM can be used to store non volatile data of the program , sometimes you need to write arrays even multidimensional. The way I do it is by using EEMEM attribute. EMMEM is used to allocate space in EEPROM.
I use the Macros given below to write or read to EEPROM. you have to use #include I would be precise . below is the Code.
#include
//////////////////////////////////////////////////////////////////////////
// Macros and # Defines
//write block to EEPROM
#define eepw(message,EEADDR,BLKSIZE) eeprom_write_block((const void*)message,(void*)EEADDR,BLKSIZE);
//read block from EEPROM
#define eepr(readblck,EEADDR,BLKSIZE) eeprom_read_block((void*)readblck,(const void*)EEADDR,BLKSIZE);
uint8_t EEMEM eepstring[15];
Example use
eepw("sample test 1",eestring, 15); // "writes sample test1" to eestring in EEprom ,
char d[15]; //array in ram
eeprom_read(d, eestring[0],15); // reads the data and puts it in d[]
Its very handy to keep track of time in embedded programs. In this post I will implement a function called millis() which can be used to track time. Arduino users will be familiar with this one. I would be doing it for AVR MCUs you can easily port it for others. this function returns the number of milliseconds since the MCU began running the current program. This number will overflow (go back to zero), after approximately 50 days.
It uses a hardware timer , in this post i will use timer0 . The first step is to initialize timer0 and interupts. lets start.
void timer0(){
// To set clock:
// 1MHZ is 1,000,000 ticks per second
// 1000 milli in 1 second
// xMHZ = 1000millis
// so MHZ/millis gives # HZ per millis
// (HZ/millis)/prescaler= Top counter number
// EG:for 8MHZ clock
// 8000000/1000
// 8000.0000000000
// 8000/256
// 31.2500000000 TOP counter
//set CTC (clear timer on compare match mode)
TCCR0A = (1< <WGM01);
//sets prescaler clkIO/256 ***THIS MIGHT CAUSE ISSUES SETS FOR ALL CLOCKS**!!!!
TCCR0B = (1<<CS02);
//sets interrupt enable for OCF0A (TIMER_COMPA_vect)
TIMSK0 = (1<<OCIE0A);
//sets TOP counter match A at 31
OCR0A = 31;
}
volatile uint32_t millis()
{
uint32_t mill;
uint8_t oldSREG = SREG;
// remember last value of interrupts
// disable interrupts while we read timer0_millis or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_millis)
cli();
mill = millis_count;
SREG = oldSREG; // rewrite reg value to turn back on interrupts
return mill;
}
In the code shown above we have initialized timer/counter 0 to make an interrupt after every millisecond. Next we have to update our millisecond count.
Just wanted to share this small piece of information that can help many . If you want to Run your AVR at 8MHz from the internal oscillator you need to disable the CLK/8 Fuse. You can do this by burning new fuse values. This can also be done in you main function as well. Below is a piece of code that will change the pre-scaler to zero.
// set the clock speed to "no pre-scaler" (8MHz with internal osc or
// full external speed)
// set the clock prescaler. First write CLKPCE to enable setting of clock the
// next four instructions.
CLKPR=(1<