Ashok R
Published © GPL3+

Sketch Drive Car

This project aims at controlling a car through a trajectory traced by the user on a screen running windows or android

AdvancedFull instructions provided24 hours4,572
Sketch Drive Car

Things used in this project

Hardware components

FRDM Board
NXP FRDM Board
×1
HC-05 Bluetooth Module
HC-05 Bluetooth Module
×1
L293DNE
×1

Hand tools and fabrication machines

CodeWarrior IDE

Story

Read more

Schematics

Sketch Drive Car Schematic

not updated , iwill update it soon

Windows App Source

Code

Sketch Drive Car Source

C/C++
/*
 * AppMain.c
 *
 *  Created on: Mar 9, 2014
 *      Author: sony
 */


#include "AppMain.h"
#include "I2C1.h"
#include "AS1.h"
#include "AD1.h"
#include "MMA8451.h"
#include "Routing.h"


#define DEBUG

byte bv[4];
byte DELAY[]= "<DLY00000>";
byte RUN[] = "<RUN00000>";
byte DATA[] = "DAT";
byte TDATA[10] = "<NOP00000>";


void App_Run(void)
{

Bat_Voltage = ReadADC();
if(Bat_Voltage < 1.8)
	RLED_ON();
else
	RLED_OFF();

// Charging Mode Check

#ifndef DEBUG
while(ReadBits_GetBit(0)){
	Bat_Voltage = ReadADC();
	
	PackData(DATA,Bat_Voltage,CarAcc.Speed);

	GLED_ON();
}
GLED_OFF();
//BLED_ON();
#endif


while(1){
	
Calibrate();	
	
ParseData();
AccRead();

CarAcc.Speed = GetSpeed();
//preX = AccelX;

Bat_Voltage = ReadADC();
PackData(DATA,Bat_Voltage,CarAcc.Speed);

//WAIT1_Waitms(1000);

if(Car.start && Car.mode){
	
	TestDrive();

}


	if(Car.start && !Car.mode){	
		
	   if(istart){
		   prevDirection = Car.Direction;
		   istart = false;
	   }
	   SetSpeed();	
	
	   
	   
		if (prevDirection != Car.Direction){
			Car.isTurning = true;
			SendString(DELAY);
			if(Car.Reverse)
			RunReverse();
			else
			RunDrive();		
			SendString(RUN);
			Car.isTurning = false;
		}
		

	}
	else{
		istart= true;
		SetOff();
	}


	
	
	if(Car.lightON){
		
		LLIGHT_ON();
		RLIGHT_ON();
		
	}
	else
	{
		LLIGHT_OFF();
		RLIGHT_OFF();
	}
	
	

}


}
	



void App_Init()
{

	BLED_OFF();	
	LLIGHT_ON();
	RLIGHT_ON();
	
Car.Reverse = 0;
istart = true;
Car.isTurning = false;
Car.isMoving = false;
Car.Speed = 0;
Car.moveBkd = 0;
Car.moveFwd = 0;
Car.moveLeft = 0;
Car.moveRight = 0;
Car.mode = 0;
WAIT1_Waitms(1000);

TurnDly[0] = 1100;
TurnDly[1] = 1200;
TurnDly[2] = 1300;
TurnDly[3] = 1400;
TurnDly[4] = 1500;
TurnDly[5] = 1600;
TurnDly[6] = 1700;
TurnDly[7] = 1800;
TurnDly[8] = 1900;
TurnDly[9] = 2000;

EngSpeed[0] = 40;
EngSpeed[1] = 45;
EngSpeed[2] = 50;
EngSpeed[3] = 55;
EngSpeed[4] = 60;
EngSpeed[5] = 65;
EngSpeed[6] = 70;
EngSpeed[7] = 75;
EngSpeed[8] = 80;
EngSpeed[9] = 85;

CarSpeed[0] = 0;
CarSpeed[1] = 40;
CarSpeed[2] = 44;
CarSpeed[3] = 48;
CarSpeed[4] = 52;
CarSpeed[5] = 56;
CarSpeed[6] = 60;
CarSpeed[7] = 64;
CarSpeed[8] = 68;
CarSpeed[9] = 72;
CarSpeed[10] = 76;
CarSpeed[11] = 80;
CarSpeed[12] = 84;
CarSpeed[13] = 88;
CarSpeed[14] = 92;

LLIGHT_OFF();
RLIGHT_OFF();
	


}


void SendChar(byte data){
	
AS1_SendChar(data);
	
}

void SendString(byte *str) {
  while(*str!='\0') {
	  AS1_SendChar(*str);
    str++;
  }
}

void SetOff()
{
	
	
	PWM1_SetDutyMS(0);
	PWM2_SetDutyMS(0);
	
	
}


float ReadADC()
{
	
	float voltage;

	 AD_finished = FALSE; /* reset flag */
	(void)AD1_Measure(FALSE); /* AD_finished will be set to TRUE once */
	while(!AD_finished) {
	/* do something else here... */
	}
	/* AD_finished set to TRUE by the interrupt to indicate the result is ready */
	(void)AD1_GetValue16(&adc_val); /* get the result into value variable */


	voltage = (float) ((3.0f * adc_val) / 0xffff);
	
	return voltage;
}

void SetSpeed()
{
		
		if(!Car.Reverse){
		
			PWM1_SetDutyMS(0);	
			PWM2_SetDutyMS(EngSpeed[Car.EngineSpeed]);
		}
		else
		{
			
			PWM2_SetDutyMS(0);	
			PWM1_SetDutyMS(EngSpeed[Car.EngineSpeed]);
	
		}
	
	
	
}

void TestDrive(){
	

			if(!Car.Reverse){
				
				PWM1_SetDutyMS(0);		
				PWM2_SetDutyMS(CarSpeed[Car.Speed/10]);
			}
			else{
				PWM2_SetDutyMS(0);		
				PWM1_SetDutyMS(CarSpeed[Car.Speed/10]);
			}

				
		
		if(Car.moveLeft && !Car.moveRight ){
			
			TurnLeft();
		}
		
		if(!Car.moveLeft && Car.moveRight ){
			
			TurnRight();
		}
		if(!Car.moveLeft && !Car.moveRight ){
			
			TurnOff();
		}

	
	
	
	
	
}

void PackData(byte *cmd,float voltage,uint8_t speed)
{
	byte volt;
	
	TDATA[0] = '<';
	TDATA[1] = cmd[0];
	TDATA[2] = cmd[1];
	TDATA[3] = cmd[2];
	
	volt = voltage*10;
	
	TDATA[4] = (byte) (volt/10) + '0';
	TDATA[5] = (byte) (volt%10) + '0';
	TDATA[6] = (byte) (speed/100) + '0';
	TDATA[7] = (byte) ((speed/10)%10) + '0';
	TDATA[8] = (byte) (speed%10) + '0';
	TDATA[9] = '>';
	
	
}

void ParseData()
{
	
	//Stream Data Format
	
	//>>>  1010	 32   x 	x	 000000    x       x	        x	    	 x		0	   x	  x	   x    x     x      xxx    x   1010   <<<
	//	   ID	 Len  Mode  Dir  Data	   ReEN    EngineSpeed  TurnDelay    start  pause  Light  FWD  BKD  Left  Right  Speed  NA  EID
	
	
	Car.mode = RxBuf[6]-'0';
	Car.Direction = RxBuf[7]-'0';
	//Car.Xval = (RxBuf[8]-'0')*100 + (RxBuf[9]-'0')*10 +(RxBuf[10]-'0')*1;
	//Car.Yval = (RxBuf[11]-'0')*100 + (RxBuf[12]-'0')*10 +(RxBuf[13]-'0')*1;
	Car.Reverse = (bool) (RxBuf[14]-'0') & 0x01; 
	Car.EngineSpeed = (RxBuf[15]-'0')*1;
	Car.TurnDelay = (RxBuf[16]-'0')*1;	
	Car.start = (bool)(RxBuf[17]-'0') & 0x01;
	//Car.stop = (bool)~(RxBuf[17]-'0') & 0x01;
	//Car.pause = (bool)(RxBuf[18]-'0') & 0x01;
	Car.lightON = (bool)(RxBuf[19]-'0') & 0x01;
	Car.moveFwd = (bool)(RxBuf[20]-'0') & 0x01;
	Car.moveBkd = (bool)(RxBuf[21]-'0') & 0x01;
	Car.moveLeft = (bool)(RxBuf[22]-'0') & 0x01;
	Car.moveRight = (bool)(RxBuf[23]-'0') & 0x01;
	Car.Speed = (RxBuf[24]-'0')*100 + (RxBuf[25]-'0')*10 +(RxBuf[26]-'0')*1;
	
	
	

}


void Calibrate (void)
{

	unsigned int count1 = 0;


	
	do{
	
		AccRead();
	CarAcc.sstatex = CarAcc.sstatex + AccelX;  //Accumulate Samples
	CarAcc.sstatey = CarAcc.sstatey + AccelY;
	count1++;
	}while(count1!=0x0400); 	//1024 times
	
	CarAcc.sstatex = CarAcc.sstatex>>10;    //Divide by 1024
	CarAcc.sstatey = CarAcc.sstatey>>10;
		
	
}



uint8_t GetSpeed(void)
{
	
	unsigned char count2=0;

	
	do{
		
	
		CarAcc.accelerationx[1]=CarAcc.accelerationx[1]+ AccelX;
		CarAcc.accelerationy[1]=CarAcc.accelerationy[1]+ AccelY;
		count2++;
		
	}while(count2!=0x40);     
		
		
	CarAcc.accelerationx[1]=CarAcc.accelerationx[1]>>6;  //division by 64	
	CarAcc.accelerationy[1]=CarAcc.accelerationy[1]>>6;
	
	CarAcc.accelerationx[1] = CarAcc.accelerationx[1] - CarAcc.sstatex; //eliminate zero reference
	CarAcc.accelerationy[1] = CarAcc.accelerationy[1] - CarAcc.sstatey; // to obtain positive and negative acceleration
	

	
	
	//First X Integeration
	
	CarAcc.velocityx[1] = CarAcc.velocityx[0] + CarAcc.accelerationx[0] + ((CarAcc.accelerationx[1]-CarAcc.accelerationx[0])>>1);
	
	
	//First Y Integeration
	
	CarAcc.velocityy[1] = CarAcc.velocityy[0] + CarAcc.accelerationy[0] + ((CarAcc.accelerationy[1]-CarAcc.accelerationy[0])>>1);
	
	
	CarAcc.accelerationx[0] = CarAcc.accelerationx[1];  // The current acceleration value must be sent to previous acceleration
	
	CarAcc.accelerationy[0] = CarAcc.accelerationy[1];
	
	
	CarAcc.VX=CarAcc.velocityx[1]-CarAcc.velocityx[0];
	CarAcc.VY=CarAcc.velocityy[1]-CarAcc.velocityy[0];
	

	CarAcc.velocityx[0] = CarAcc.velocityx[1];  // The current velocity value must be sent to previous velocity
	
	CarAcc.velocityy[0] = CarAcc.velocityy[1];
	
	

return CarAcc.VX;
	
	
	
}

Sketch Drive Car WinApp.7z

Plain text
No preview (download only).

Credits

Ashok R

Ashok R

37 projects • 102 followers
Hobbyist/Engineer/Director/Animatior

Comments