PMOS driver for arduino

In case you are looking to make a Buck controller based on arduino, this is a simple circuit to drive the PMOS transistor mainly for buck circuit applications.

This circuit is simple and only consist of NPN and 1 PNP transistor. The circuit above is part of my MPPT solar charger circuit.

Continue reading “PMOS driver for arduino”

Arduino controlled bass mid treble and input selector with tda7419

If you are looking to control your audio with arduino, here’s it is. It uses TDA7419 chip which has a lot of features for controlling your audio. It has 4 input selector, bass control, mid control, treble control, loudness control and a built-in 7 band spectrum analyzer.

Continue reading “Arduino controlled bass mid treble and input selector with tda7419”

Adafruit oled library problem Workaround

My latest project includes an OLED display with 128×64 resolution and 1.3inch size. In search for a library, I found Adafruit oled libray problem. The display does not seem to work with this library. Upon doing some research, I gave up and do this work around instead.

Continue reading “Adafruit oled library problem Workaround”

Arduino Clock with 16×2 LCD and Rotary Encoder without RTC

Here a simple arduino code for clock function without using RTC. If you only want to display the time and not the date, you do not need an RTC. The built-in crystal oscillator of the arduino is accurate enough for time displaying function.

Schematic Diagram

This is simple to build.

Code

[code lang=”c”]
// 1602 clock by tataylino.com
#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
int x = 0;
int minute = 1;
int hour = 12;
int sec = 0;
int am = 0; //1 = morning
bool up = false;
bool down = false;
bool display_update = true;
bool amtopm = false;

int backled = 9;
int button = 13;
int val = 0;
int aState;
int aLastState;

void setup() {
pinMode(button, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
// pinMode(13, OUTPUT);
pinMode(backled, OUTPUT);
analogWrite(backled, 255);
// set up the LCD’s number of columns and rows:
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(“Orasan”);

//set timer1 interrupt at 1Hz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
// set compare match register for 1hz increments
OCR1A = 15624;// = (16*10^6) / (1*1024) – 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei();//allow interrupts
}
void display() {
if(hour >= 10) {
lcd.setCursor(0, 2);
lcd.print(hour);
} else {
lcd.setCursor(0, 2);
lcd.print(“0”);
lcd.setCursor(1, 2);
lcd.print(hour);
}

lcd.setCursor(2, 2);
lcd.print(“:”);

if(minute >= 10) {
lcd.setCursor(3, 2);
lcd.print(minute);
} else {
lcd.setCursor(3, 2);
lcd.print(“0”);
lcd.setCursor(4, 2);
lcd.print(minute);
}

lcd.setCursor(5, 2);
lcd.print(“:”);
if(sec >= 10){
lcd.setCursor(6, 2);
lcd.print(sec);
} else {
lcd.setCursor(6, 2);
lcd.print(“0”);
lcd.setCursor(7, 2);
lcd.print(sec);
}
if(am == 1){
lcd.setCursor(8, 2);
lcd.print(“am”);
} else {
lcd.setCursor(8, 2);
lcd.print(“pm”);
}
}

void counting_time(){
if(minute < 0 ) {
minute = 59;
hour–;
}
if(hour < 1){ hour = 12; } if (sec >= 60) {
sec = 0;
minute++;
}
if (minute >= 60) {
hour++;
minute = 0;
}
if (hour >=13) {
hour = 1;
}
if(hour == 12 && minute == 0) { // to make sure only 1 am to pm transition
if(amtopm == true) {
amtopm = false;
if(am == 1){
am = 0;
} else {
am = 1;
}
}
}else{
amtopm = true;
}
}

ISR(TIMER1_COMPA_vect){//timer1 interrupt 1Hz
sec++;
counting_time();
if(display_update) {
display();
}
}

void loop() {
val = digitalRead(button); // read button
if (val == HIGH) {
//lcd.setCursor(0, 0);
//lcd.print(“o”);
//minute++;
//delay(500);
}
aState = digitalRead(A3);
if (aState != aLastState){
// If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
if (digitalRead(A2) != aState) {
display_update = false;
minute ++;
counting_time();
if(minute >= 10) {
lcd.setCursor(3, 2);
lcd.print(minute);
} else {
lcd.setCursor(3, 2);
lcd.print(“0”);
lcd.setCursor(4, 2);
lcd.print(minute);
}
display_update = true;
} else {
display_update = false;
minute –;
counting_time();
if(minute >= 10) {
lcd.setCursor(3, 2);
lcd.print(minute);
} else {
lcd.setCursor(3, 2);
lcd.print(“0”);
lcd.setCursor(4, 2);
lcd.print(minute);
}
display_update = true;
}
}
aLastState = aState; //
}

[/code]

 

 

 

Arduino programmer is not responding problem

Just recently I made a project with arduino nano and used my old working board. To my surprise I got an error that the programmer is not responding. After some debugging I found out that there is no problem on my wires or drivers. It looks like arduino just updated their bootloader with no backward compatibility. There is not option on the board “ATmega328P ( Old Bootloader)” but it doesn’t work.

So I decided to just re-program my arduino nano with the latest bootloader. The bootloader hex file can be found on the directory below:

To program, I used power debugger and connected it like below:

After I programmed the latest bootloader, my arduino is alive again. 🙂

The real problem here is that arduino updated their bootloader with no backward compatibility. The best fix is to program your arduino board with the latest firmware that you can find on the arduino folder on your program files directory. You can use any AVR programmer. You can also use your working arduino to program another arduino here: https://www.arduino.cc/en/Tutorial/ArduinoISP

 

Measuring Voltage using arduino

If you want to monitor a voltage level that is higher than the voltage that arduino input can handle, you will just need to use a voltage divider.

About the Circuit

Basically you will only need a voltage divider if you are measuring voltage that is greater than the max input voltage of your arduino.

“Vin” is where you will input the voltage to be measured. R1 and R2 forms a voltage divider to decrease voltage of the Vin. The value of R1 will be based on the max voltage that your Vin can reach.

Let R2 = 100k, you can choose higher value but check the computed value of R1 will be easy to find.

The maximum voltage that this arduino nano can handle is 5V so we will use that to compute for the value of R1. R1 is computed such that Va0 level is 5V at Maximum input voltage.

Computing for R1

For instance you are expecting the maximum input voltage is 15V, add about 10% to that to have a little headroom. So you will use 16.5V for your computation.

Vinmax = 16.5V
Va0max = 5V

R1 = (Vinmax – Va0max)/Iin

Iin = Va0max/R2

R1 = (R2(Vinmax – Va0max))/Va0max

R1 = R2((Vinmax/Va0max)-1)

replacing the value to the equation yields:

R1 = (100k)((16.5/5)-1)

R1 = 230k

Computing on software

Arduino will give you the digital value and not the actual voltage value so you need to compute and consider the voltage divider to be able to get the actual input voltage.

Actual voltage is computed as:

Vadc = (adc_val/adc_res)*adc_vref

where:

adc_val – digital value from the adc module
adc_res – ADC resolution, 1024 in case for arduino nano
adc_ref – ADC reference voltage. it is 5V default on arduino nano. This can be changed via program

And consider the voltage divider:

Va0 = Vin(R2/(R1+R2))

Vin = (Va0(R1+R2))/R2

Vin = (R1Va0 + R2Va0)/R2

Vin = Va0((R1/R2) + 1)

And since Va0 = Vadc then…

Vin = ( adc_vref(adc_val/adc_res))((R1/R2) + 1)

Now let’s put it into practice:

int adc_val;
int adc_ref;
int adc_res;
double Vin;
int R1;
int R2;

adc_ref = 5;
adc_res = 1024;
R1 = 230; //k
R2 = 100; //k

// read analog input

adc_val = analogRead(0);  // 0 = Connected to A0

Vin = (adc_ref(adc_val/adc_res))((R1/R2)+1);

Displaying it into the LCD

// include the library code:
#include <LiquidCrystal.h>// initialize the library with the numbers of the interface pins – The numbers
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

int adc_val;
int adc_ref;
int adc_res;
double Vin;
int R1;
int R2;

void setup() {
adc_ref = 5;
adc_res = 1024;
R1 = 230; //k
R2 = 100; //k

    // set up the LCD’s number of columns and rows:
lcd.begin(16, 2);
   // Print a message to the LCD
lcd.print(“hello, world!”);
}

void loop() {
// read analog input
adc_val = analogRead(0);  // 0 = Connected to A0
Vin = (adc_ref(adc_val/adc_res))((R1/R2)+1);
// set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
    // print the number of seconds since reset:
lcd.print(“Voltage:”);
lcd.setCursor(1, 1);
lcd.print(Vin );

}

Related: CONNECTING ARDUINO NANO TO 16×2 LCD

Connecting High Power LED to Arduino

Arduino digital can only drive a few milliamps and up to 5V only. You can’t use it to drive a high power LED directly. If you want to drive a high power LED using Arduino, you need to use a driver.   There are 2 options, 1 is to use a transistor driver or use an IC driver. A transistor driver is the easiest option, it will only require 3 components(2 resistors and 1 transistor). The transistor is either a MOSFET or a BJT.

Figure 1 – Driving LED using BJT

In the example above, we are using a NPN transistor for driving a LED. R1 is used to limit the current coming out of the Arduino. Without R1, Arduino digital pin might got damaged due to high current sinking from the output pin. The output voltage of the Arduino will be limited to the Vbe(base-emitter voltage) of Q1 without R1. While R2 limits the current for the LED.

R2 = (VDD – VLED – VCEsat)/ILED
where:
VLED – voltage of the LED
VCEsat – saturation voltage of the Q1 at ILED current
ILED – current of the LED at VLED
VDD – supply voltage(in this example: 5V)

  • Note: You do not need R2 if VLED is equal to VCC. For example if voltage of the LED is 12V and your supply is also 12V, R2 will be useless.

Minimum value of R1:

R1 = (Vout – Vbe)/Iin
where:
Vin – output voltage of Arduino (usually 5V or 3.3V)
Vbe – base-emitter voltage of Q1(usually around 0.5 – 0.7V)
Iin – Max output current of Arduino ( ~10-20mA)

Max value of R1:
this is a little tricky so let’s derive the equation, shall we?

IC = Ib * β
replace Ib with equation from the circuit:
IC = ((Vin – Vbe)/R1) * β
IC = ILED
ILED = ((Vin – Vbe)/R1) * β
ILED/β = (Vin – Vbe)/R1
R1/β = (Vin – Vbe)/ILED

R1 = ((Vin – Vbe) * β)/ILED

where:
β – transister beta or HFE
ILED – LED current
Vbe – base-emitter voltage of the transistor
Vin – output voltage of arduino
IC – Collector current of the transistor

If you have computed lower maximum resistance than the minimum resistance then you should consider changing your transistor with higher HFE. You may consider using  a darlington transistor or a MOSFET.



LED Driver IC

LED driver IC is a bit expensive but it has some advantage. It can supply a constant current which leads to more constant brightness especially if you are using multiple LED’s at a time. It also has some sort of overload protection. It is also more efficient and very ideal for battery powered applications which will have longer battery life. It is not usually simple because it is usually using switching power supply topology.

 

Figure 2 – LED driver IC

Dimming LED with Arduino

Dimming is done by using PWM or Pulse Width Modulation. PWM works by rapid turning on and off of the output. The brightness of the LED is controlled by controlling the ratio of the on versus the off state. PWM is easily done with Arduino, thanks to its very simple library.

Sample code:

int ledPin = 9; // LED connected to digital pin 9
int analogPin = 3; // potentiometer connected to analog pin 3
int val = 0; // variable to store the read value

void setup() {
    pinMode(ledPin, OUTPUT); // sets the pin as output
}

void loop() {
val = analogRead(analogPin); // read the input pin
     analogWrite(ledPin, val / 4); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255
}

 

Note: analogWrite command only works on PWM pins. 

 

-tataylino.com

Arduino Controlled Bass Mid Treble and input selector

My LC75341 project was a bit of a disappointment. It was working ok but it only offers bass and treble controls. The frequency response is not that good. It has very limited controls. I decided to stop that project because it is not what I am looking for. Now after lots of research, I stumble upon this digitally controlled bass mid treble IC from ST. What is great is that it has 7 band spectrum analyzer feature and a differential input. Plus it also has Q and frequency control and a subwoofer output. This is almost exactly what I want to do.

Continue reading “Arduino Controlled Bass Mid Treble and input selector”