Friday, August 17, 2012

RoboCar: A Robotic Awesomness

Robotic Cars are truly full of awesomeness, it is a world full of engineering, design, challenges, coding, components, datasheet, hardware and reverse engineering sometimes.

It is about transforming a simple 10$ RC car





To XBee enabled, sensor armed, camera monitored, MCU + Steering Wheel + Brake/Acceleration Pedals controlled awesomeness





Photos after fixing IR Proximity Sensor/ Headlight LEDs/ Camera


My plan is to build a remotely controlled car from a base station 






So, first thing I started disassembling the poor car






And the control electronics to be replaced as well




Instead of the PCB, I've added a breadboard with an ATmega328







And installed a 1.5m range IR proximity sensor from sparkfun



and through in some code, the result:
















 #include <avr/io.h>  
 #include <USART.h>  
 #include <util/delay.h>  
 #define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))     //Macro to set an individual pin  
 #define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))     //Macro to reset (clear) an individual pin  
 void init_ADC(void);  
 uint8_t ADC_read(uint8_t pin);  
 int main (void)  
 {  
      DDRB=0xFF;     //PORTB as output  
      DDRD=0xFF;     //PORTB as output  
      //PB0-PB5 + PD6 + PD7 are used for the 8-Bit DAC, PB6 & PB7 are used for XTAL  
      init_ADC();     //Setup ADC  
      uint8_t VAL;//Used to read ADC value  
      for (;;)  
      {  
           VAL = ADC_read(0);     //Read ADC Value; (connected to PC0)  
           PORTD=VAL;     //Output the 8-bit number through PORTD (8-Bit Port)  
           SETBIT(PORTB,PB0);     //PB0 connected to WR signal, DAC read the data on WR rising edge  
           CLEARBIT(PORTB,PB0);// Prepare for next reading  
      }  
      return 0;  
 }  
 void init_ADC(void)          //Prepare ADC Module  
 {  
      DDRC = 0x00;  
      PORTC= 0x00;  
      ADMUX |= (1<<ADLAR);     //Input from ch.0 , reference is taken from AREF pin, Left Adjusted Result  
      ADCSRA |= (1<<ADEN) | (1<<ADSC);     //Enable ADC, Start Conversion, no CLK prescaling  
      loop_until_bit_is_clear(ADCSRA, ADSC);  
 }  
 uint8_t ADC_read(uint8_t pin)     //Read an 8-Bit ADC  
 {  
      ADCSRA |= _BV(ADSC);  
      loop_until_bit_is_clear(ADCSRA, ADSC);  
      return ADCH;  
 }  





Original Signal




Signal out of ADC


On the screen...





[ To be Continued]


Saturday, April 28, 2012

HD44780 Custom Character Generator - Update

Yeaaaaaaaaaaa, HD44780 CCG  gets an update

I've added a Menu which enables saving and loading



you can save files in "ccg" extensions

here is an example "HappyFace.ccg"





Download the new version (V1.001) of HD44780 Custom Character Generator

github: https://github.com/MuazSalah/HD44780_CCG

Friday, April 27, 2012

HD44780 Custom Graphics Generator

Previously, I used to use Sparkfun's serial LCD, which is really neat and very easy to use, however, it is a lil buggy sometimes and the PCB takes wider space. So, I decided to go back in time and use the bare LCD with HD44780 controller (also I got it from sparkfun).

So After I got it, my plan was to write my own code to drive it, but then my laziness beat my excitness :P

Searching in the web, I came across this really awesome and very easy to use library from Peter Fleury to drive the LCD which I tried and liked. It is really awesome to get started with these LCDs

On the example code, he shows how easy it is to create a custom character eg.: the Copyright symbol by simply defining the 0s and 1s (for this specific example two character cells are required, hence two lines)


static const PROGMEM unsigned char copyRightChar[] =
{
    0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07,
    0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00
};


so I decided to make it even easier, I made a visual basic program :)



you only need to dray on the Image area by clicking on individual pixels


The result is displayed on the Preview area, and the actual code is on the text box, very simple!




same as the above picture but inverted :D

It doesn't look like a heart? yea, excuse my drawing abilities






yea, Arabic as well :D

You can download the program form here


Saturday, April 21, 2012

Push Button ON/OFF

21st April, 2012

Ever wondered how can you keep your circuit ON using a push button rather than a toggling switch?

just like in many instruments/ mobile phones etc

the following schematic shows you how,


The idea is that you use the push button to run the circuit normally, and then, very fast (in the beginning of your code if the cct contain a microcontroller) send a signal to close a switch (could be a relay or whatever)

Example on ATmega328

#include <avr/io.h>  
#include <util/delay.h>  
#include <USART.h>  
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))  
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) 

int main(void)  
{  
    init_usart();  
    SETBIT(DDRB,0);  //Output pin (ON/OFF)
    CLEARBIT(DDRB,1); //Input to change time
    SETBIT(PORTB,1);  //Enable Pull-Up resistor

    for (;;)  
    {  
        for (uint16_t i=30; i>0; i--)  //repeat 15 times going down, used as delay
        {  
            printf("i=%d\n",i);  //just to see whats the current delay value
            _delay_ms(100);  //give me time to release button
            while ((PINB & 0x02)==0x02)  //loop when I don't press button
            {  
                SETBIT(PORTB,0);   //ON
                _delay_ms(i);      //i value as delay
                CLEARBIT(PORTB,0); //OFF 
                _delay_ms(i);
            }  
        }  
    }  
    return 0;  
} 


Remember that when a person pushes a button and releases it, he usually takes quite long (in ms), which is an enough time for the MCU to run, turn the switch ON and keep itself alive :)








26th April, 2012

So I've tried to go with only MOSFETs instead of the bulky relay, I tried this earlier:




which did not succeed as I said, so today I tried this:





which was not successful as welll :S


What am I doing wrong?!!






Thursday, February 16, 2012

Pajero Mod 1.0

Monday evening, when got in my car going back home, I suddenly got the itch to modify the car a lil.

It is annoying that there is no USB port at least for charging:



So I decided to add USB port for charging, and while I'm at it, but some blue LEDs :)

I first removed the passenger drawer


and got access to all the wire-mess inside, yay!





Air Bag!!







anyway, I started with the LED for door,
the LED is super bright and is rated for 80mA, the supply is 12v
R = V/I = 12/0.08 = 150 ohm

I soldered 150 ohm directly to the LED and tried to make the assembly in similar form-factor as the original bulb, the result:


amazing, now to my USB charger, the circuit is like:





and I added hot glue to make sure no short circuit happens

Then fixed the LED to place:



awesome!
and the USB:



now I can charge my phone :)

Friday, February 3, 2012

Battery in Salt Solution

For some reason or another, I got this silly idea of dropping a battery in a water saturated with salt :)

I thought, the salt will act as a conductor with resistance ~ 0 and Imagined all the sparking (really?! spark inside water! just imagine! :P)

I started with the Test Aperture :D

1- Resistance test leads



I cute two ~ 3 inch of steel wire and stripped out 5mm of insulation from both ends and soldered one end to binding post



which I fixed to a glass bottle's cover









And here I got some interesting results

the probes were about 7cm apart from each other (the bottle diameter is about 9cm)


resistance with tap water ~ 70K ohm
resistance with salt water ~ 14K ohm

what a finding!!!!!

This means with the battery inside the water, it won't effectively be a short-circuit, no sparking!!!!


it was kinda depressing, but I continued, I added temperature sensor (LM335) to MCU (ATmega168) to serial port on PC and then I logged the data


Once in water, I saw small bubbles forming on the negative pin and then going out, this continued and continued and continued without spark!!!, after sometime I got bored and stopped the data recording.


you can find the recorded raw data here : Temperature Readings

I graphed it on excel and I found this:



the x-axis numbers are just the index numbers, they dont mean anything, but it is actually for about 16 mins of continues data recording, I assume the ADC clock is maximum which is half the MCU clock which was 16MHz so the ADC is 8MHz

the y-axis is the decimal value of the ADC, so you can go:

V = 5*(y/1023)

V is the actual voltage read by the ADC
5 is the ADC reference voltage
y is the number from the file (the decimal value)
1023 is the ADC counts, for 10-bit ADC (2^10)

then to get the actual temperature, you use the formula from the data sheet of LM335 which is

V = 10mV / K

so

T (K) = V * 0.01

and you get the temperature in Kelvin, however, you might need to do initial calibration with a know temperature and then you subtract/add the calibration value to all other measured values.

Since I don't have this equipment, I used the raw decimal value to see the trend


here, I put the bottle outside and went to sleep, the next day:




















what a mess!

of course, everything including the poor LM335 inside will all go to be disposed  off the universe!

Shall I count it as a fail?!
why the resistance was large?!!
How can I decrease it?!!






Sunday, January 1, 2012

How Fast Relays Are?

From the time I learned about relays, I wondered if they can be used to make an H-Bridge for motors, I asked my professor and he said that you can't because they are slow.

I never knew how slow, till today, so I wrote a small code on my AVR ATmega168 microcontroller

basically, the code send an ON -> delay(x) -> OFF -> delay(x)

where x is a value (in ms) changing every time a button is pressed going down from 15 ms to 1ms

1:  #include <avr/io.h>  
2:  #include <util/delay.h>  
3:  #include <USART.h>  
4:  #define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))  
5:  #define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))  
6:  int main(void)  
7:  {  
8:       init_uart();  
9:        SETBIT(DDRB,0);  //Output pin (ON/OFF)
10:       CLEARBIT(DDRB,1); //Input to change time
11:       SETBIT(PORTB,1);  //Enable Pull-Up resistor
12:       for (;;)  
13:       {  
14:            for (uint16_t i=15; i>0; i--)  //repeat 15 times going down, used as delay
15:            {  
16:                 printf("i=%d\n",i);  //just to see whats the current delay value
17:                 _delay_ms(100);  //give me time to release button
18:                 while ((PINB & 0x02)==0x02)  //loop when I don't press button
19:                 {  
20:                      SETBIT(PORTB,0);   //ON
21:                      _delay_ms(i);      //i value as delay
22:                      CLEARBIT(PORTB,0); //OFF 
23:                      _delay_ms(i);
24:                 }  
25:            }  
26:       }  
27:       return 0;  
28:  } 

And then connected the relay, driving it with a NPN



I found that min time is 2ms, at 1ms, no switching will occur ( i was getting highly rippled 5v)



and here is an awesome sound of 1~15ms switching, at 0:16 the time is 1ms



~2ms (500Hz) is the min time (max freq) u can switch a typical relay