There have been continuous innovations in the automotive industry whether it be the use of Near Field Communication in the upcoming car models or the futuristic self-driving cars. These innovations are driven by one motive and that is to make the drive more and more comfortable and smart or safer. This project is also a similar attempt to make the car drives safer by modifying the headlights to adaptive headlights.
The headlights of any car are generally fixed. Therefore, on turning the car during night drive, drivers face problem as the fixed headlights are not actually throwing off light on the path where the driver has been turning around. This makes the driving at night prone to accidents and the driver needs to turn around corners with extra caution. If the headlights are made to turn along with the direction car has turned, a driver can get the full view of the actual path he is driving through around the corners. This is possible by mounting the headlights to servo motors and automate the servos in coordination with the steering of the car. The steering movement can be traced out using a mechanical assembly attached with a potentiometer.
In this project, this innovation has been realized using the Arduino boards and connecting the servo motor circuit to the control circuit installed at steering through 434 RF Module. Instead of modifying a car’s body to the change Headlight’s assembly, the project has demonstrated the application using the LEDs mounted over RC servos. The control circuit is also not fabricated with full mechanical assembly on a steering but a potentiometer is used in the project to illustrate raw functioning. Though, the project can be given a real life-size by implementing the car body modification with mounting rotatable headlights to the car and installing the control circuit with proper mechanical assembly on the steering.
Components Required
Sr. No. | Components Required | Quantity |
---|---|---|
1 | RF Rx Module (434Mhz) | 1 |
2 | RF Tx Module (434Mhz) | 1 |
3 | Arduino pro mini | 2 |
4 | LED | 2 |
5 | Pot 10k | 1 |
6 | Servo motor | 2 |
7 | Battery – 9V | 2 |
8 | Breadboard | 2 |
9 | Connecting wires |
Fig.1 : Block Diagram of Arduino based Adaptive Headlights for Cars
Circuit Connections
There are two circuits in the project – Steering Control Input Circuit and Headlight Servo circuit. In the steering control input circuit, a 10K ohm potentiometer is connected to A2 analog pin of the Arduino Pro Mini. The other two terminals of the potentiometer are connected to VCC and ground. The Arduino is interfaced to RF transmitter by connecting the serial input pin (Pin 2) of the RF transmitter to pin 12 of the Arduino. An antenna can be used at the pin 4 of RF transmitter to improve transmission signal, however, it is optional and not really needed as the operational range of the project will be limited to the front dimensions of the car. On life-size implementation of the project, some mechanical assembly needs to be designed so that the potentiometer knob rotates with respect to the rotation of steering wheel.
At Servo circuit, an RF receiver is connected to the another Arduino board by connecting serial out pin (Pin 2) of the receiver module to pin 11 of the Arduino. Again an antenna can be used with the RF receiver which is optional only to improve signal strength. There are two LEDs connected at pin 9 and 7 of the Arduino which are assumed the car headlights in the circuit. These LEDs are mounted on the Servo motors. There are two RC servo motors connected to data pins 5 and 6 of the Arduino with respect to the headlight representing LEDs.
Fig. 2: Prototype of Transmitter Circuit for Adaptive Car Headlights
How the Circuit Works
In order to understand the working of this project, it is important to understand how a potentiometer works. The potentiometer is a strip of resistance material. It’s one terminal is connected to the anode and other terminal is connected to the cathode. The voltage output is drawn from a third terminal which has slideable contact with the resistive material. As the contact closes to anode end, the voltage output gets closer to supply voltage due to low resistance. When the contact slides away from the anode end, the voltage output is dropped due to a higher resistance between the anode and output terminal because the resistance is increased proportionally to the length of resistive material between them. At the steering end, the potentiometer is set to a mid value for default, as the steering rotates either direction, the contact of the potentiometer either slides away or closer to anode end and the output voltage from the potentiometer is reduced or increased with respect to the default value.
The potentiometer’s voltage output is read as analog data at the A2 pin of the transmitter side Arduino. The reading is converted to character form and transmitted over RF using the VirtualWire library functions in the program code.
The potentiometer reading is detected at the RF receiver and serially out to the pin 11 of the receiver side Arduino. The program code at the receiver side Arduino detects the potentiometer reading by reading the transmitted character buffer and converting the reading to an integer value. The value is compared with a default calibrated value and the direction of turning is judged accordingly. By detecting the direction car has turned, PWM signals are passed to the RC servos for rotating along the direction of turning. The LEDs remain ON by default and rotates along with the servo as they are mounted on them. Check out the transmitter side Arduino code to learn how analog reading from the potentiometer is detected in the code and converted to character form and serially transmitted over RF. Then, check out the receiver side Arduino code to learn how character buffer is read and interpreted to an integer value and based on the value read, the servos are operated.
Fig. 3: Prototype of Receiver Circuit for Adaptive Car Headlights
Programming Guide
On the transmitter side Arduino, first, the program code imports the required standard libraries. The VirtualWire library is required to read the analog reading from pin A2. Global variables ledPin and Sensor1Pin are declared and mapped to Pin 13 where transmission progress indicator LED is connected and Pin A2 where output pin of the potentiometer is connected respectively. A variable Sensor1Data is declared to store potentiometer voltage reading. A character array Sensor1CharMsg is declared to stored decimal representation of the potentiometer reading.
A setup() function is called where indicator LED pin is set to output while sensor connected pin is set to input mode using pinMode() function. The baud rate of the Arduino is set to 9600 bits per second using the serial.begin() function. The baud rate for serial output is set to 2000 bits per second using the vw_setup() function of the VirtualWire library.
A loop() function is called where the analog reading (in terms of voltage measurement at the pin) is fetched using the analogRead() function and stored in “Sensor1Data” variable. The potentiometer reading (an integer value) is converted to the character of base 10 using itoa() function and stored in Sensor1CharMsg array.
The potentiometer reading is serially out as human-readable ASCII text using the Serial.print() and Serial.println() function.
The transmission progress indicator LED is switched on by passing a HIGH to pin 13. The character message containing the potentiometer reading is sent serially using the vw_send() function and vw_wait_tx() is used to block transmission until a new message is available for transmission. The LED at pin 13 is switched OFF by passing a LOW to indicate successful transmission of the message.
This ends the transmitter side Arduino code.
On the receiver side Arduino, the program code first imports the required standard libraries. The VirtualWire library is imported to receive potentiometer reading from RF. The pins where servos are connected are mapped to “servo” and “servo1” variables and other global variables – “angle” to represent the angle of rotation for servos and “PWM” for respective pulse width duration are declared. The “Sensor1Data” is declared to store integer value of reading and Sensor1CharMsg array is declared to hold character representation of reading through RF.
A setup() function is called where baud rate of the Arduino is set to 9600 bits per second. The servo and LED connected pins are set to digital output using the pinMode() functions. The pins where LEDs are connected are set to HIGH to keep the LEDs switched ON by default.
The RF transmitter and receiver module does not have Push To Talk pin. They go inactive when no data is present to transmit or receive respectively. Therefore vw_set_ptt_inverted(true) is used to configure push to talk polarity and prompt the receiver to continue receiving data after fetching the first character. The baud rate for serial input is set to 2000 bits per second using vw_setup() function. The reception of the data is initiated using vw_rx_start().
The null character is detected in the buffer stream so that no garbage value gets stored. The characters received from the buffer are converted to the integer value and stored in “Sensor1Data” variable.
The variable value along with relevant strings enclosed is passed to the microcontroller’s buffer and Sensor1Data value is passed to servoPulse and servoPulse1 custom functions as a parameter to rotate servos.
In servoPulse function, the Sensor1Data which has been passed as angle parameter is taken and multiplied by 11 then added to 1000 to get pulse width duration in microseconds. The servo connected pin is set to HIGH and delay of calculated duration is passed. The HIGH output to servo connected pin is then terminated.
The same logic as implemented in servoPulse function is implemented as it is in servoPulse1 function.
This ends the receiver side Arduino code.
You may also like:
Project Source Code
###
#include// LED's const int ledPin = 13; // Sensors const int Sensor1Pin = A2; // const int Sensor2Pin = 3; int Sensor1Data; //int Sensor2Data; char Sensor1CharMsg[4]; void setup() { // PinModes // LED pinMode(ledPin,OUTPUT); // Sensor(s) pinMode(Sensor1Pin,INPUT); // for debugging Serial.begin(9600); // VirtualWire setup vw_setup(2000); // Bits per sec }void loop() { // Read and store Sensor 1 data Sensor1Data = analogRead(Sensor1Pin); // Convert integer data to Char array directly itoa(Sensor1Data,Sensor1CharMsg,10); // DEBUGSerial.print("Sensor1 Integer: "); Serial.print(Sensor1Data); Serial.print(" Sensor1 CharMsg: "); Serial.print(Sensor1CharMsg); Serial.println(" "); delay(10);// END DEBUG digitalWrite(13, true); // Turn on a light to show transmitting vw_send((uint8_t *)Sensor1CharMsg, strlen(Sensor1CharMsg)); vw_wait_tx(); // Wait until the whole message is gone delay(12);} // END void loop... #includeint servo = 5; int servo1 = 9; int angle; int pwm; // Sensors int Sensor1Data; // RF Transmission container char Sensor1CharMsg[4]; void setup() { Serial.begin(9600); pinMode(servo, OUTPUT); pinMode(servo1, OUTPUT); pinMode(3, OUTPUT); pinMode(8, OUTPUT); digitalWrite(3,HIGH); digitalWrite(8,HIGH); // sets the digital pin as output // VirtualWire // Initialise the IO and ISR // Required for DR3100 vw_set_ptt_inverted(true);// Bits per sec vw_setup(2000); // Start the receiver PLL running vw_rx_start(); } // END void setup void loop(){ uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; // Non-blocking if (vw_get_message(buf, &buflen)) {int i; // Message with a good checksum received, dump it. for (i = 0; i < buflen; i++) { // Fill Sensor1CharMsg Char array with corresponding // chars from buffer. Sensor1CharMsg[i] = char(buf[i]); }// Null terminate the char array // This needs to be done otherwise problems will occur // when the incoming messages has less digits than the // one before. Sensor1CharMsg[buflen] = ''; // Convert Sensor1CharMsg Char array to integer Sensor1Data = atoi(Sensor1CharMsg); // DEBUG Serial.print("Sensor 1: "); Serial.println(Sensor1Data); servoPulse(servo, Sensor1Data); servoPulse1(servo1, Sensor1Data); }} void servoPulse (int servo, int angle) { pwm = (angle*11) + 1000; // Convert angle to microseconds digitalWrite(servo, HIGH); delayMicroseconds(pwm); digitalWrite(servo, LOW); delay(15); // Refresh cycle of servo } void servoPulse1 (int servo1, int angle) { pwm = (angle*11) + 1000; // Convert angle to microseconds digitalWrite(servo1, HIGH); delayMicroseconds(pwm); digitalWrite(servo1, LOW); delay(15); // Refresh cycle of servo }###
Circuit Diagrams
Project Video
Filed Under: Tutorials
Filed Under: Tutorials
Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.