here's my code. I'll try to show you the circuit diagram but I've not wrote it down yet
features:
[]config button to enter config mode to set max+min pedal, tb, and idle pot positions, then saves it all to eeprom
[*]reads both pedal pots (they are linear or none of this code would ever work)
[]reads both tb pots
[*]evaluates each and essentially generates a percentage of how open they are (in future this can be changed, i.e. multiply by 200 instead of 100, to increase the accuracy
[]idle potentiometer that can be set by hand to set the minimum amount of open
[*]always opens at the same speed (same pwm value) see below, currently set to 94
[*]once the desired tb position is reached, changes the pwm value to one which isn't strong enough to open it further, but strong enough to keep it where it is
problems I have:
[]sometimes when the circuit starts up, it's as if one or both of the fets are left open, making a short circuit. It happenes once in about 10 times and basically blows the fet
[*]i've tried several things to check that both pots are giving the same value, but unable to find the perfect solution
[]if for whatever reason they don't match, ignoring them isnt an option, because I can't either put the pwm to 0 because it'll close too much until they match again, and leaving it as it is will cause it to open too far until they match again
[*]if it's all running well, the slight variations in the readings (e.g. +/- 1%) happen quite regularly, and cause it to vibrate ever so slightly (this could also be caused by overshooting by having a too high pwm value to open the throttle since the last trip round the loop), i'm not sure which but i think it's the first one
#include <pic.h>
#include "stdio.h"
#include <math.h>
#define PORTBIT(adr,bit) ((unsigned)(&adr)*8+(bit))
static bit confbutton @ PORTBIT( PORTD,3 );
static bit target @ PORTBIT( PORTC, 4);
static bit Perror @ PORTBIT( PORTC, 5);
static bit Terror @ PORTBIT( PORTC, 6);
void delay100u(unsigned int k);
void WriteEEPROM(unsigned char address, unsigned char value);
unsigned char ReadEEPROM(unsigned char address);
unsigned int ReadTpos();
unsigned int ReadTpos2();
unsigned int ReadPpos();
unsigned int ReadPpos2();
unsigned int ReadTidle();
static unsigned char cycles;
static char freq = 12;
//unsigned int initial = 1;
//static bit button @ PORTBIT(PORTC,0);
void main()
{
//vars
unsigned char Tpos;
unsigned char Tpos1;
unsigned char Tpos2;
unsigned char Ppos;
unsigned char Ppos1;
unsigned char Ppos2;
unsigned char TIpos;
//consts
unsigned char Teq;
unsigned char TImin;
unsigned char TImax;
unsigned char Tmin;
unsigned char Tmax;
unsigned char Tmin1;
unsigned char Tmax1;
unsigned char Tmin2;
unsigned char Tmax2;
unsigned char Pmin;
unsigned char Pmax;
unsigned char Pmin1;
unsigned char Pmax1;
unsigned char Pmin2;
unsigned char Pmax2;
//percentages
unsigned int TIperc;
unsigned int Teqperc;
unsigned int Pperc;
unsigned int Pperc1;
unsigned int Pperc2;
unsigned int Tperc;
unsigned int Tperc1;
unsigned int Tperc2;
unsigned int i;
unsigned int configmode = 0;
//error catching
unsigned int changecount = 0;
unsigned int modeopen = 0;
unsigned int modeclosed = 0;
//float result;
cycles = 30*freq/4;
TRISA = 0b11111111; // input
TRISE = 0b00000001;
TRISB = 0; // output
TRISC = 0;
TRISD = 0b00001000;//1000
// ADCON0 = 0b01011001;
ADCON1 = 0b10000001;//5ad 1ref
PR2 = 0b11101001;
T2CON = 0b00000111;
CCP1CON = 0b00101100;
CCP2CON = 0b00101100;
PORTC = 0b00000000;
CCPR1L = 0;
CCPR2L = 0;
PORTD = 0b00000000;
delay100u(2);
//etb zero point calibration
for (i = 0 ; i < 20; i++) {
delay100u(2);
Teq = ReadTpos();
Tmin = ReadEEPROM(0b00000000);
Tmax = ReadEEPROM(0b00000001);
Tmin1 = Tmin;
Tmax1 = Tmax;
Tmin2 = ReadEEPROM(0b00000010);
Tmax2 = ReadEEPROM(0b00000011);
Pmin = ReadEEPROM(0b00000100);
Pmax = ReadEEPROM(0b00000101);
Pmin1 = Pmin;
Pmax1 = Pmax;
Pmin2 = ReadEEPROM(0b00000111);
Pmax2 = ReadEEPROM(0b00001000);
TImin = ReadEEPROM(0b00001001);
TImax = ReadEEPROM(0b00001010);
Teqperc = (int)(((Teq - Tmin)*100)/(Tmax - Tmin));
}
for (;;) {
//IDLE POSITION RESISTOR
//LISTEN FOR CONFIG BUTTON PRESS
if (confbutton == 1) {
configmode = configmode + 1;
delay100u(30);
while (confbutton == 1) {
configmode = configmode;
}
}
if (configmode == 1) {
//flash leds in a sequence
PORTB = 0b00011000;
delay100u(15);
PORTB = 0b00100100;
delay100u(15);
PORTB = 0b01000010;
delay100u(15);
PORTB = 0b10000001;
delay100u(15);
PORTB = 0b01000010;
delay100u(15);
PORTB = 0b00100100;
delay100u(15);
PORTB = 0b00011000;
delay100u(15);
}
if (configmode == 2){
//close throttle as far as it'll go
CCPR1L = 0;
CCPR2L = 94;//44 idle
PORTD = 0b00000010;//10
//throttle close position
PORTB = 0b10000000;
//read AN3 (push throttle to close)
//record value
Tmin = ReadTpos();
Tmin1 = Tmin;
Tmin2 = ReadTpos2();
WriteEEPROM(0b00000000,Tmin);
WriteEEPROM(0b00000010,Tmin2);
delay100u(30);
PORTB = Tmin;
delay100u(30);
PORTB = Tmin2;
delay100u(30);
}
if (configmode == 3) {
//open throttle as far as it'll go
CCPR1L = 94;
CCPR2L = 0;
PORTD = 0b00000001;
//throttle max position
PORTB = 0b01000000;
//read AN3 (push throttle to open)
//record value
Tmax = ReadTpos();
Tmax1 = Tmax;
Tmax2 = ReadTpos2();
WriteEEPROM(0b00000001,Tmax);
WriteEEPROM(0b00000011,Tmax2);
delay100u(30);
PORTB = Tmax;
delay100u(30);
PORTB = Tmax2;
delay100u(30);
}
if (configmode == 4) {
//reset throttle position
CCPR1L = 0;
CCPR2L = 0;
PORTD = 0b00000000;
//pedal min position
PORTB = 0b00100000;
//read AN1 (keep pedal at 0)
//record value
Pmin = ReadPpos();
Pmin1 = Pmin;
Pmin2 = ReadPpos2();
WriteEEPROM(0b00000100,Pmin);
WriteEEPROM(0b00000111,Pmin2);
delay100u(30);
PORTB = Pmin;
delay100u(30);
PORTB = Pmin2;
delay100u(30);
}
if (configmode == 5) {
//pedal max position
PORTB = 0b00010000;
//read AN1 (push medal to max)
//record value
Pmax = ReadPpos();
Pmax1 = Pmax;
Pmax2 = ReadPpos2();
WriteEEPROM(0b00000101,Pmax);
WriteEEPROM(0b00001000,Pmax2);
delay100u(30);
PORTB = Pmax;
delay100u(30);
PORTB = Pmax2;
delay100u(30);
}
if (configmode == 6) {
//idle min
PORTB = 0b00001000;
TImin = ReadTidle();
WriteEEPROM(0b00001001,TImin);
delay100u(30);
PORTB = TImin;
delay100u(30);
}
if (configmode == 7) {
//idle max
PORTB = 0b00000100;
TImax = ReadTidle();
WriteEEPROM(0b00001010,TImax);
delay100u(30);
PORTB = TImax;
delay100u(30);
}
if (configmode == 8) {
PORTB = 0b00011000;
delay100u(15);
PORTB = 0b00100100;
delay100u(15);
PORTB = 0b01000010;
delay100u(15);
PORTB = 0b10000001;
delay100u(15);
PORTB = 0b01000010;
delay100u(15);
PORTB = 0b00100100;
delay100u(15);
PORTB = 0b00011000;
delay100u(15);
configmode = 0;
}
if (configmode == 0) {
TIpos = ReadTidle();
for (;;){
Tpos = ReadTpos();
if (confbutton == 1) {
TIpos = ReadTidle();
}
Ppos = ReadPpos();
PORTB = Ppos;
if (Ppos <= Pmin1) {
Ppos = Pmin + 1;
}
Ppos1 = Ppos;
TIperc = (int)(((TIpos - TImin)*100)/(TImax - TImin));
//if ((Pperc1 - 5) > (Pperc2 + 5)) { //trying to work out if they are incorrect readings
// if (Pperc1 != Pperc2) { //i think it didnt work
// Perror = 0;
//use last good Pperc
// }
// else {
// Perror = 1;
Pperc = (int)(((Ppos - Pmin)*(100-TIperc))/(Pmax-Pmin));
Pperc = Pperc + TIperc;
// }
//if ((Tperc1 - 5) > (Tperc2 + 5)) { // same as above
// if (Tperc1 != Tperc2) {
// Terror = 0;
// //use last good Tperc
// }
/// else {
// Terror = 1;
// }
Tperc = (int)(((Tpos - Tmin)*100)/(Tmax - Tmin));
//navigate to idle position
if (Pperc > Teqperc) {
// if (modeclosed == 1) {
// if (changecount < 10) {
// changecount = changecount + 1;
// }
// else {
// modeclosed = 0;
// }
// }
// else {
// modeopen = 1;
// changecount = 0;
if (Tperc > Pperc) { //close on spring
//PORTC = 0b00000000;
target = 0;
CCPR1L = 5;
CCPR2L = 0;
PORTD = 0b00000001;
}
else if (Tperc < Pperc) { //open at 50
//PORTC = 0b00000000;
target = 0;
CCPR1L = 94;
CCPR2L = 0;
PORTD = 0b00000001;
}
else { //let it idle
//PORTC = 0b11110000;
target = 1;
CCPR1L = 58;//14 2.2 //28 2.0
CCPR2L = 0;
PORTD = 0b00000001;
}
// }
}
else if (Pperc < Teqperc) {
// if (modeopen == 1) {
// if (changecount < 10) {
// changecount = changecount + 1;
//
// }
// else {
// modeopen = 0;
// }
// }
// else {
// modeclosed = 1;
// changecount = 0;
if (Tperc < Pperc) { //closec on spring
//PORTC = 0b00000000;
target = 0;
CCPR1L = 0;
CCPR2L = 5;
PORTD = 0b00000010;
}
else if (Tperc > Pperc) { //openc at 50
//PORTC = 0b00000000;
target = 0;
CCPR1L = 0;
CCPR2L = 94;
PORTD = 0b00000010;
}
else { //let it idle
//PORTC = 0b11110000;
target = 1;
CCPR1L = 0;
CCPR2L = 58;//14 2.2 //28 2.0
PORTD = 0b00000010;
}
// }
}
else {
//reached exactly 0?
//
target = 1;
CCPR1L = 0;
CCPR2L = 0;
PORTD = 0b00000000;
}
}
}
}
}
void delay100u(unsigned int k)
{
unsigned char count1;
unsigned char count2;
unsigned char count3;
unsigned char count4;
for (count2=k ; count2>0 ;count2 = count2-1) {
for (count1 = k ; count1 > 0 ; count1 = count1 - 1) {
for (count3 = k ; count3 > 0 ; count3 = count3 - 1) {
for (count4 = k ; count4 > 0 ; count4 = count4 - 1) {
continue;
}
}
}
}
}
unsigned char ReadEEPROM(unsigned char address)
{
// EECON1 = 0;
EEPGD = 0;
EEADR = address;
RD = 1;
return EEDATA;
}
void WriteEEPROM(unsigned char address, unsigned char value) {
unsigned char previousGIEstate;
EEADR = address;
EEDATA = value;
EEPGD = 0;
WREN = 1;
previousGIEstate = GIE;
GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1;
while (WR == 1) {
;
}
WREN = 0;
GIE = previousGIEstate;
}
unsigned int ReadTpos() {
unsigned int r;
//etb
ADCON0 = 0b01100001;//AN4 //was AN3
//ADCON0 = 0b01010001;
delay100u(1);
ADGO = 1;
while (ADGO == 1) {
//continue;
}
r = ADRESH;
CARRY = 0;
r = r << 8;
r = r + ADRESL;
r = r >> 2;
return r;
}
unsigned int ReadTpos2() {
unsigned int r;
//etb
ADCON0 = 0b01101001;//AN5 //was an4
//ADCON0 = 0b01010001;
delay100u(1);
ADGO = 1;
while (ADGO == 1) {
//continue;
}
r = ADRESH;
CARRY = 0;
r = r << 8;
r = r + ADRESL;
r = r >> 2;
return r;
}
unsigned int ReadTidle() {
unsigned int r;
//pot
ADCON0 = 0b01010001;//AN2
delay100u(1);
ADGO = 1;
while (ADGO == 1) {
//continue;
}
r = ADRESH;
CARRY = 0;
r = r << 8;
r = r + ADRESL;
r = r >> 2;
return r;
}
unsigned int ReadPpos() {
unsigned int r;
//pedal
ADCON0 = 0b01001001;//AN1
delay100u(1);
ADGO = 1;
while (ADGO == 1) {
//continue;
}
r = ADRESH;
CARRY = 0;
r = r << 8;
r = r + ADRESL;
r = r >> 2;
return r;
}
unsigned int ReadPpos2() {
unsigned int r;
//pedal reverse
ADCON0 = 0b01000001;//AN0
delay100u(1);
ADGO = 1;
while (ADGO == 1) {
//continue;
}
r = ADRESH;
CARRY = 0;
r = r << 8;
r = r + ADRESL;
r = r >> 2;
return r;
}