Saturday 30 June 2012

AVR- Intro to I/O ports in C Language instead of Arduino/Processing Language


As sometimes we do need to use a faster code, i have been looking into using AVR coding in C , as opposed to the normal Arduino/Processing language that makes away with it all, allowing us to use a simplified dumbed down version of it.


For this basic introductory tutorial, I'll be assuming that you have a basic grasp/knowledge of Digital Logic systemsbinary numberslogic gates and Boolean algebra.  at least the basics of C Programming ( which can be replaced at least with some experience/knowledge of the  Arduino/Processing language, for purposes of this exercise, or any High Level programming language) and of course, some basic knowledge of Electronic circuits and the Ohm's Law.


So, as first thing, ( and i will come back to this in more detail at another time) i have to let you know the structure of a program, as it is different from the Arduino way.
Arduino, as you probably read by now, made it much easier for beginners and newcomers to code, by only needing us to use a void setup()  and a void loop().


But in AVR we will be using C, (  avr-gcc C compiler  , version 4.3.0  or later at least so we will have to do it differently , by the rules. I will just leave here a template of a basic program with a loop, so it doesnt end on us.
Personally i use CodeBlocks ( that even has a modified version for Arduino with a basic simulatoor and all: HOW COOL IS THAT  ?! lol )


#include <avr/io.h>  // In this line, called a header file is included avr/io.h , 
// an AVR device-specific I/O definitions library that register 
// names defined, used in the later stages. Check 
// http://www.nongnu.org/avr-libc/user-manual/modules.html 
// for more info and reference */

int main(void)  // This is the main part of the program, where it actually starts. */
{
  while(1)
    // Note that we use a '1' as the argument to the while loop, because anything other than '0' is 
    //a logical true. Therefore the while loop condition will never be anything other than 
logically true, and the program 
    //will continue to execute indefinitely  */
  {
    // Code would be in here if needed to execute over and over and over ... endlessly */
  }               
}



As starting poing, i'd recommend the ATMega328 Datasheet everytime you dont understand a term here used (hardware related), or have doubts regarding the hardware side of the architecture of the micrcontroller itself.


Also, we will use the pin mapping of the ATMega 328 as a guidelline for this exercise !




So, first a quick explanation of the concept of the PORTs in the ATMega. To note the fact that there are 3 types of functions we can perform with the uC's : Controlling, sensing and communicating.
For test purposes we will start with controlling a led, as it is the HELLO WORLD of electronics and also in Uc's world.


Each AVR implements 3 different set of GPIO registers (GPIO - General Purpose Input / Output). The registers used are:


  • DDRx- Data direction register for port x


x corresponds to A , B , C , D , etc. (Depending on the number of ports used by the AVR chip that we are using at the time). Bit (1) in the register  for output. bit (0) (cleared)  for input.


  • PINx - Address for input port x .


State of the port. Independent of the setting of Data Direction bit DDRx, the port pins can be read through the PINx Register bit.
In order to use the data read from port pin, first you have to change port’s data direction to input. This is done by setting bits in DDRx to zero. If port is made output, then reading PINx register will give you data that has been output on port pins.
Bit 1 if pin is "HIGH"; if bit 0 , port pin is "LOW".


  • PORTx - Data register for port x


This register is used for two purposes:  To output data ( when port is configured as output) and to activate/deactivate pull up resistors ( when port is configures as input).
For pins that were connected by DDRx on input, the internal pull-up resistors can be enabled or disabled via PORTx  (1 = enabled).

So for purpose of this exercise we will use the PORTDPD0 to PB7) which are the Digital pins 0, 1, 2, 3, 4, 5, 6 and 7 on the Arduino Uno/ATMega328.


OK, first maybe we should define the state of the direction of the data; We already know it can be INPUT or OUTPUT.So, when defined as an INPUT, he will be waiting  to sense a voltage ( or "listen" to it).
When the pins are in OUTPUT mode, use a logic of either 5 V or 0V; HIGH and LOW; 1 or 0 when in an OUTPUT mode !

And how can we control through the uC?!?

So, it is easy: All we have to do is simply tell Pin5 on PORTD to output 5 volts( Digital Pin 5 on Arduino UNO ; Maybe you can try this on PORTC IF YOU USING A MEGA... Digital pin 37 to 30). Note that this must be accomplished for each pin we wish to use in our circuit.

So, first, we will have to define the PINs we want to use as outputs in the following register:

DDRD = 0b00000001;

*There are several ways to set pin5 of in the PORT B to output.This is just one way, in bynary in this case. Mind the fact that This notation is only available in GNU C and not defined in ISO-C.  But we will talk about that at a later stage.

So, let me explain in detail what we doing here.  "DDRD" refers to the Data Direction Register for port D; "0b" is to tell the compiler that what follows is the binary expression of a number ( as we are using bynary in this instance; Mind that you can also do it in Hexadecimal, to which we will come to , on another time); and the "1" on the end denotes the pin 0 position (the first pin in port D).
Mind the fact that there are 8 pins for port B; pins 0 through 7. And maybe the brightest sparks noticed already that we are using also 8 digits in our code statement. So each digit represents a pin on the port, and we can use the individual digits to specifically refer to any one of the pins in port D.
So the '1' at the end of our code statement refers to the first pin in port B, which in this case is pin 0. (To note the fact that C and C++ are ZERO-BASED languages, so the first index of a data structure refers to, is the zero'th element; the second index refers to the first element, etc.). So, based on the explanation of the registers given above we can see that to apply a HIGH logic to a pin, we should use PORTD in this case, which is  the Data register for port D.
So the result is as follows:

PORTD = 0b00000001;



#include <avr/io.h>  

int main(void)         // For now we are just going to turn a led on */
{
  DDRB = 0b00000001;   // Data Direction Register setting pin0 to output and the remaining pins as input
  PORTB = 0b00000001;  // Set pin0 to 5 volts

  while(1)
  {
    // * "empty" loop, we including so the code keeps being executed. Maybe you would 
    // like to try it without the while loop 
    // Code would be in here if needed to execute over and over and over ... endlessly */
  }

  // * Never reached * / 
  return  0 ;                  
}


-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=



=>Regarding Hexadecimal, Binary and decimal<=


Just a quick cheat-sheet for those who might need it ( some is from the port 
manipulation post i done a while ago):







Binary| Hex
0000  |  0
0001  |  1
0010  |  2
0011  |  3
0100  |  4
0101  |  5
0110  |  6
0111  |  7
1000  |  8
1001  |  9
1010  |  A
1011  |  B
1100  |  C
1101  |  D
1110  |  E
1111  |  F

(precede with 0x)


                                                                                                                             
                                                                                                                              ERRATA: The right-hand picture has an error in 1 decimal, as it is easy seen ( I DIDNT,lol ! Thanks, dropes !)


So in those terms, this code

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to output
}

could be written as:
void setup()
{
  DDRD = 0xFF; // set PORTD (digital 7~0) to output
}


Same way that


void loop()
{
  PORTD = B00000000; //Digital 0~7  to LOW
}
Could be done as
void loop()
{
  PORTD = 0x00; //Digital 0~7  to LOW
}


To be continued...


Useful Reference links:

http://sensorsweep.tripod.com/binary.html - Has a nice animation as well, counting in bynary so you can get a better understanding

http://www.inetdaemon.com/tutorials/basic_concepts/number_systems/binary/index.shtml

http://www.mathsisfun.com/binary-decimal-hexadecimal-converter.html - nice handy converter between hexa, Bynary and decimal

Thursday 28 June 2012

Android ADK2012 is here and Arduino Due platform


ADK2012 board
Google has unveiled at Google IO their new  Accessory Development Kit for Android mobile phones and tablets, the ADK2012
The ADK2012 is based on the upcoming Arduino Due platform and the new Arduino IDE that supports programming ARM targets.
Currently the IDE works only on the Google ADK board released at Google IO, while the official launch of the Arduino Due is due later in the year.





Tuesday 26 June 2012

DIY DUBSIREN Kits (test PCB Boards)

My test PCB Boards( without ground plane, as they only test boards) just arrived...
So, after my tests, we will finally have available soon the DIY DUBSIREN Kits available !! 2 Diff models !! Nuff works happening !! 



Friday 22 June 2012

DubResistors and the LedHeads

Dub-Resistors and the Led Heads



2 small updates on my doings...

1st
PickIt 2 debugger/inline programmer and logic analyzer for the 8 bits family of the PICs. 
Also a PIC16F887 chip for me to play with and learn some assembler language/programming.
Cant get lower level programming than that, can it ?!?

PS: A week later "had" to decide for the PIC16F886 as well, so i can have more choices while learning. I am actually finding it quite intuitive, thanks to a tutorial of an expert on PIC's,  A. Sérgio Sena whom's website you can find here http://www.antoniosergiosena.com/ . 
To note the fact he is a certified PIC instructor/teacher( is that  what i should call him ?!? lol).
I had recently looked into several tutorials on Assembler language for PIC's, and had realised that it wasnt as scary as i first thought, few years back, and even the way PIC's work is far from scary as well. This of course was first based on my first impression back then, when i compared it and AVR's to Arduino language for example, which is so dumbed down and so easy to catch up.
While you can get a led blinking , and even other basic projects adapted by you in a few dozen minutes with Arduino, with PIC took me a few good hours just to be able to upload a test project ( and even then considering i already have enough experience with other platforms like AVR and have some good knowledge of the basic in programming and what a compiler is. To be honest PickIt 2 makes it so easy, along with MpLab IDE).




2nd
Never was into robots and RC cars as a kid, but now that im a grown up and can build them my own way, it seems quite interesting !!! 
Anyway, its not for me, just building and developing the code for it ( despite i did buy another one for me as well eh eh eh )
U can see the ultrasonic sensors, so it SEES the obstacles and can avoid them... Will be also adding remote control soon !!
One lucky kid who will be having it !!

 If you think this is fun, you should see the really expensive collectible one i been working on for a week and half !!



Thursday 21 June 2012

Infra red Decoder

As i have been playing with robots, i decided either to use Infra red for a remote control, or Radio Control.
So for now ill be testing some Infra red.
As we all have older remotes at home lost in our drawers, i decided t use the Arduino Mega to decode one of them and use it maybe.

So lets start with what a Infra red emitter/receiver does in a remote control
http://en.wikipedia.org/wiki/Remote_control
Also check
http://www.sbprojects.com/knowledge/ir/index.php

So, i ordered a TSOP2438 IR receivr that works with a modulated carrier at 38Khz.
And i got it connected like this, after reading the datasheet:
-Yellow to Digital Pin 19 ( remember i am using the Mega 2560...)
-Black to ground
-Red to 5V


So, lets see the code

/* Raw IR decoder sketch!
 
 This sketch/program uses the Arduno and a TSOP2438 to 
 decode IR received. This can be used to make a IR receiver
 (by looking for a particular code)
 or transmitter (by pulsing an IR LED at ~38KHz for the
 durations detected 
 
 Code is public domain
 */ 
// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//uint8_t IRpin = 2;
// Digital pin #2 is the Pin D19 on the Mega2560(PD2
// see http://arduino.cc/en/Hacking/PinMapping168 for the 
// UNO pin mapping with ATMega168/328

#define IRpin_PIN      PIND
#define IRpin          2
 
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
 
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20 
 
// we will store up to 100 pulse pairs (THIS IS A LOT)
uint16_t pulses[100][2];  // pair is high and low pulse 
uint8_t currentpulse = 0; // index for pulses we're storing
 
void setup(void) {
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");
}
 
void loop(void) {
  uint16_t highpulse, lowpulse;  // temporary storage timing
  highpulse = lowpulse = 0; // start out with no pulse length
 
 
//  while (digitalRead(IRpin)) { // this is too slow!
    while (IRpin_PIN & _BV(IRpin)) {
     // pin is still HIGH
 
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);
 
     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
 
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE)  && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;
 
  // we read one high-low pulse successfully, continue!
  currentpulse++;
}
 
void printpulses(void) {
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
  for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.print(" usec, ");
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
    Serial.println(" usec");
  }
}


So , i then pointed the remote to the receiver and pressed the UP in the cursor,
and this is what i got...




If we ignore the first OFF pulse (its just the time from when 
the Arduino turned on to the first IR signal received) and 
the last ON pulse (it the beginning of the next code), 
you'll find the power code is:


920  usec, 820 usec, 
900  usec, 820 usec, 
1760 usec, 820 usec,
900  usec, 820 usec, 
900  usec, 820 usec, 
900  usec, 1680 usec, 
1780 usec, 1680 usec, 
1760 usec, 1680 usec, 
1760 usec, 820 usec, 
920  usec, 22624 usec, 
920  usec, 800 usec, 
920  usec, 800 usec, 
1780 usec, 820 usec, 
900  usec, 820 usec, 
900  usec, 820 usec, 
900  usec, 1680 usec, 
1780 usec, 1660 usec, 
1780 usec, 1680 usec, 
1780 usec, 800 usec

(...to be continued)

PS- Of course we can use a Oscilloscope instead...




Tuesday 19 June 2012

32BITS , 80Mhz Pinguino with PIC32MX440F256H

Yes, the ready-to-use version arrived, and its from one of my favourite developers of boards out there-OLIMEX !! They have got us used to top quality stuff, no doubt !!
So THIS BOARD , with a PIC32 MX440F256H, uses the PINGUINO IDE , with the same kind of language that Arduino got us used to !
I am also doing a PINGUINO DIY version of it with the PIC32MX250F128B DIP, that takes advantage of the USB bootloader for the PIC32.














Saturday 16 June 2012

INTRO to port manipulation

Someone asked me about what sometimes comes in more direct code in Arduino, when we use port manipulation to make it a bit faster or for convenience, etc...
So a likkle explanation here !


As we know, Arduino made it much easier for beginners to create code in sketches by doing away with the complexity seen before in uC's ( port registers, header files, linker files, etc etc)
With just one button , most people are blinking a led and really understanding the basics of it in 10 minutes( most of it will be installing and downloading the IDE anyway).

But time comes that we will get to hit the limits of such simplicity, as their own functions, etc do take more time. For that, AVR way of doing things is the way to go.
So, by doing it directly improves the speed quite considerably.
So in this case we will do away with digitalWrite()/digitalRead(), by doing some port manipulation directly..


ATMega328 has three port registers that  can be altered to set the digital and analogue I/O pins. A port register is a kind of byte variable that we can change on the microcontroller, in order to control the state of various I/O ports. We have three port registers to work with:

D – digital pins 7 to zero (Port D)
B – digital pins 13 to eight (Port B)
C – analogue pins 5 to zero (Port C!)



In void setup(), we will use

DDRy = Bxxxxxxxx
where y is the register type (B/C/D) and  xxxxxxxx  are 8 bits that determine if a pin is to be an input or output. Use 0 for input, and 1 for output. The LSB (least-significant bit [the one on the right!]) is the lowest pin number for that register.
So , then, to control the port pins, we will use

PORT y  = Bxxxxxxxx
where y is the register type (B/C/D) and  xxxxxxxx  are 8 status bits = 1 for HIGH, 0 for LOW. That can be seen in the following example:

// Digital 0 to 7 set to outputs, then on/off using port manipulation

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void loop()
{
  PORTD = B11111100; // digital 2~7 HIGH, digital 1~0 LOW
  delay(1000);
  PORTD = B00000011; // digital 2~7 LOW, digital 1~0 HIGH
  delay(1000);
}




So, we have set the digital pins 7~0 to output in void setup().
Then we alternate them on and off , pins 2 to 7 with 0 and 1 always in opposite state to the rest .

So, why would we want to do that ?!?
Well, John Boxall done some measurements and he came up with these results :



The code as a first test:


// Digital 0 t o7 set as outputs, then on/off using digitalWrite()

void setup()
{
  for (int a=0; a<8; a++)
  {
    pinMode(a, OUTPUT);
  }
}

void loop()
{
  for (int a=0; a<8; a++)
  {
    digitalWrite(a, HIGH);
  }
  for (int a=0; a<8; a++)
  {
    digitalWrite(a, LOW);
  }
}

And the frequency was  14.085 kHz.
This would be a way of doing it.
Another way would be:


// Digital 0~7 set to outputs, then on/off using individual digitalWrite() 

void setup()
{
  for (int a=0; a<8; a++)
  {
    pinMode(a, OUTPUT);
  }
}

void loop()
{
  digitalWrite(0, HIGH);
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
}

A small speed boost, the frequency has increased to 14.983 kHz. 

Then he used same type of port manipulation with:

// John Boxall - October 2011
// Digital 0~7 set to outputs, then on/off using port manipulation

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void loop()
{
  PORTD = B11111111;
  PORTD = B00000000;
}


And  the frequency measurements – 1.1432 MHz! 




However, as he notes, there are a few things to take note of:


You can’t control digital pins 0 and 1 (in bank D) and use the serial monitor/port. For example if you set pin zero to output, it can’t receive data!


Also , keep this in mind, if you are not aware of it-


Binary| Hex
0000 |  0
0001 |  1
0010 |  2
0011 |  3
0100 |  4
0101 |  5
0110 |  6
0111 |  7
1000 |  8
1001 |  9
1010 |  A
1011 |  B
1100 |  C
1101 |  D
1110 |  E
1111 |  F

(precede with 0x)


So in those terms, this code

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to output
}

could be written as:

void setup()
{
  DDRD = 0xFF; // set PORTD (digital 7~0) to output
}


Same way that


void loop()
{
  PORTD = B00000000; //Digital 0~7  to LOW
}
Could be done as

void loop()
{
  PORTD = 0x00; //Digital 0~7  to LOW
}

*PS- Someone asked "...why is digitalWrite() relatively that much slower?"

Well, here is the source code for digitalWrite() – quite a lot of code to convert compared against port manipulation:
void digitalWrite(uint8_t pin, uint8_t val)
{
  uint8_t timer = digitalPinToTimer(pin);
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *out;

  if (port == NOT_A_PIN) return;

  // If the pin that support PWM output, we need to turn it off
  // before doing a digital write.
  if (timer != NOT_ON_TIMER) turnOffPWM(timer);

  out = portOutputRegister(port);

  if (val == LOW) {
    uint8_t oldSREG = SREG;
    cli();
    *out &= ~bit;
    SREG = oldSREG;
  } 
  else {
    uint8_t oldSREG = SREG;
    cli();
    *out |= bit;
    SREG = oldSREG;
  }
}



Tuesday 12 June 2012

Endeavours with Robots and Sonar type App

Sonar type graphical app with Ultra Sonic range measurement module Model: SEN136B5B from seedstudio, Atmel Mega2560 test, to use in a robot.
 Was done using Processing language and the Ultra Sonic range measurement is programmed using Wiring Language/Arduino ( As its for a robot). Implementation will be an autonomous obstacle avoiding robot, as first instance to be upgraded incrementally !






Sonar App with ProcessingUltra Sonic range measurement module Model: SEN136B5B

















Based on work and code, with 2 different sensors  @ http://luckylarry.co.uk/arduino-projects/arduino-processing-make-a-radar-screen-part-3-visualising-the-data-from-sharp-infrared-range-finder/

g7electronica Portugal

If you are around in Portugal ( Country i was born), and into Robotics/Electronics check http://www.g7electronica.com for online shopping and personalized service as well ! !!


Se estiveres em Portugal e gostares de Robotica  e/ou Electronica da um salto a http://www.g7electronica.com para compras online, e servicos personalizados para privados/empresas ( PCBs, desenvolvimento de solucoes por medida em robotica e electronica).

Friday 8 June 2012

Direct Digital Synthesis

For a while i been exploring the several possible ways of generating sound with the Atmega 328.
So one of the good ways is always to start from the basic things !

Direct digital synthesis (DDS) is a method of producing an analog waveform— Sine wave, Square wave or Triangle are the most used and required— by generating a time-varying signal in digital form and then performing a digital-to-analog conversion.
Square, triangular, and sinusoidal waves from a DDS




There are many possibilities for frequency generation , ranging from phase-locked-loop (PLL)-based techniques for very high-frequency synthesis, to dynamic programming of digital-to-analog converter (DAC) outputs to generate arbitrary waveforms at lower frequencies.
A good example can be a signal generator, an essential tool in the arsenal of any electronics geek !!
It is also widely used in Radio frequencies, and modulation  .


So i came across this Article on Direct Digital Synthesis. http://lionel.cordesses.free.fr/gpages/DDS1.pdf

 Also check these webcasts from Analog Devices...   http://www.analog.com/en/content/WC_FUN_PLL/webcast.html
and
http://www.analog.com/en/content/WC_FUN_DDS/webcast.html

Last but not least, the good ol'Wikipedia
http://en.wikipedia.org/wiki/Direct_digital_synthesizer

Thursday 7 June 2012

Mobile Processing and Bluetooth app to control my projects...

Wow !!
 I just realized that the language Processing also has a MOBILE environment, as a replacement for J2ME( Java). 
So that means i can finally write the Apps to control whatever i want ( bluettoth, web, messaging, all with a good graphic set of libraries, 3D included...) EH EH EH
 Can i sense a possible interface with a dub siren controlled by the phone and all !?! YES !! Nokia and Android !! I will be forced to discriminate I Phones for obvious reasons( it will soon be dead anyway).
For those interested in the programming side of it, here are some links
http://mobile.processing.org
http://processing.org/
PS- Also check the blog of the person who gave me the hint at http://lusorobotica.com/ 's forum !!
http://redacacia.wordpress.com/2010/09/15/controlling-a-robot-with-bluetooth-enabled-cell-phone/




Saturday 2 June 2012

temperature sensor TMP36

Basic test, with a temperature sensor TMP36, displaying voltage, Celsius degrees and Fahrenheit degrees.
This will be added to the clock my dad asked me ( see below).