View previous topic :: View next topic |
Author |
Message |
[email protected]
Joined: 23 Jun 2012 Posts: 22
|
gear check using 2 switches |
Posted: Sun Dec 23, 2012 7:18 am |
|
|
I have used two DPDT press-release switches to find the gear shift in two wheelers. The idea is to scan the switches at each gear and relatively find the next. So I used a global declaration for integer. I am sure that this logic will work to identify the gear position. The problem is my program. Usually it doesn't work. It compiles without errors but all the LEDs glow simultaneously! Pls help me experts.
#include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=20000000)
#define S1 PIN_B1 //1st switch
#define S2 PIN_B2 //2nd switch
#define NEUTRAL PIN_B3 // 5 LED pins for representing gear
#define FIRST PIN_B4
#define SECOND PIN_B5
#define THIRD PIN_B6
#define FOURTH PIN_B7
int flag=0;//global declaration
int gear();
int neutral_gear();
int first_gear();
int second_gear();
int third_gear();
int fourth_gear();
int neutral_gear() // can change only to first gear or remain same
{
if(!input(S1)&&!input(S2))
{
flag=0; // no change in switches, so no change in flag value
return flag;
}
else if(!input(S1)&&input(S2))
{
flag=1; //switch logic changes, so flag value changes to represent 1st gear
return flag;
}
}
int first_gear() //can up-shift to 2nd or downshift to neutral or remain same
{
if(!input(S1)&&input(S2))
{
flag=1; // no change in switches, so no change in flag value
return flag;
}
else if(!input(S1)&&!input(S2))
{
flag=2; //switch logic changes, so flag value changes to represent 2nd gear
return flag;
}
else if(input(S1)&&input(S2))
{
flag=0; //switch logic changes, so flag value changes to represent neutral gear
return flag;
}
}
int second_gear() //can up-shift to third or down-shift to 2nd or remain same
{
if(!input(S1)&&!input(S2))
{
flag=2; // no change in switches, so no change in flag value
return flag;
}
else if(!input(S1)&&input(S2))
{
flag=3; //switch logic changes, so flag value changes to represent 3rd gear
return flag;
}
else if(input(S1)&&!input(S2))
{
flag=1; //switch logic changes, so flag value changes to represent 1st gear
return flag;
}
}
int third_gear() //can u-shift to fourth or down-shift to third or remain same
{
if(!input(S1)&&input(S2))
{
flag=3; // no change in switches, so no change in flag value
return flag;
}
else if(!input(S1)&&!input(S2))
{
flag=4; //switch logic changes, so flag value changes to represent 4th gear
return flag;
}
else if(!input(S1)&&input(S2))
{
flag=2;//switch logic changes, so flag value changes to represent 2nd gear
return flag;
}
}
int fourth_gear() // can remain same or down-shift to 3rd
{
if(!input(S1)&&!input(S2))
{
flag=4; // no change in switches, so no change in flag value
return flag;
}
else if(input(S1)&&!input(S2))
{
flag=3; //switch logic changes, so flag value changes to represent 3rd gear
return flag;
}
}
int gear() //for identifying the flag value
{
int r;
if(flag==0) //the previous flag value is checked for neutral gear
{
r=neutral_gear(); //check for change in flag value in neutral gear
return r;
}
else if(flag==1)
{
r=first_gear(); //check for change in flag value in from 1st gear
return r;
}
else if(flag==2)
{
r=second_gear(); //check for change in flag value in 2nd gear
return r;
}
else if(flag==3)
{
r=third_gear(); //check for change in flag value in 3rd gear
return r;
}
else if(flag==4)
{
r=fourth_gear(); //check for change in flag value in 4th gear
return r;
}
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
while(1)
{
int g;
g=gear(); //for checking the flag value
if(g==0)
{
output_high(NEUTRAL); //if flag is zero
}
else if(g==1)
{
output_high(FIRST); //if flag is one-first gear
}
else if(g==2)
{
output_high(SECOND); //if flag is two-second gear
}
else if(g==3)
{
output_high(THIRD); //if flag is three-third gear
}
else if(g==4)
{
output_high(FOURTH); //if flag is four-fourth gear
}
}
}
-I have used a global variable for the gear position.
-The logic is to check the switch logic states at each gear position.
-I have placed these switches in such a way when if a downshift occurs a switch is pressed, the same for the up-shift also.
-The switches are reset when again a up-shift or down-shift occurs.
-So I have to use separate functions for each gear position to find out the gear in use
Last edited by [email protected] on Sun Dec 23, 2012 10:10 am; edited 1 time in total |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sun Dec 23, 2012 8:04 am |
|
|
learn to use the code function. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Dec 23, 2012 8:12 am |
|
|
Use the code function, it preserves indentation so that logic flow is easier to follow.
Your code looks far too complex.
Explain exactly (in simple terms) what you want to happen.
Explain what each function is doing.
You've got several similar functions, they can probably be reduced to one (simpler) function.
From what I can see all your LEDs will glow eventually because you never turn them off!.
Mike |
|
|
[email protected]
Joined: 23 Jun 2012 Posts: 22
|
|
Posted: Sun Dec 23, 2012 10:13 am |
|
|
Sorry...
I have edited my post with code function. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Dec 23, 2012 11:46 am |
|
|
Several little comments:
1) setup_spi(SPI_SS_DISABLED);
This turns off slave select. It doesn't disable the slave. Correct syntax is:
setup_SPI(FALSE);
2) You make the common error of assuming switches switch!. Gernally, most forms of switch exhibit _bounce_. They will make and break several times for one operation. At the speed a processor works, you could possibly cycle through all the gears for one switch operation....
3) How are the switches wired?. Pull up resistors?.
4) Hopefully you have got current limiting resistors on the LED's?.
Instead of having all these separate gear routines, have a single variable (possibly an enum), for the gears. Have a keyscan routine, which returns a value (say) 0 for no change, '1' for change up, and '2' for change down. This can check the buttons a few times, and verify the switches are stably in the state, before returning the number. Then just a single routine, and if '1' is seen, it increments the gear number (if this is less than the highest allowed). If '2' it decrements (again if this is above the minimum). Nothing else.
Best Wishes |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Dec 23, 2012 11:55 am |
|
|
Now I'm even more confused.
I'd hoped for a simple explanation.
My two-wheeler had a neutral between all the gears!
How does your system know which gear it's in at switch on?
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Dec 23, 2012 12:30 pm |
|
|
Don't feel too bad Mike...I'm confused as to what a '2 wheeler' is as there's only 4 speeds involved. One of my bicycles had 3 speeds the other 18....
So I'd like to know what '2 wheeler' is....
Also not sure why DPDT switches are used since you can decode 4 unique positions with just 2 switches.00,01,10,11
Or am I missing something else??
In any event 'debouncing' must be dealt with.
Original program is way too complicated... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Dec 23, 2012 1:00 pm |
|
|
No, I don't think you are missing anything....
That is why I asked how the switches are wired. I _think_ he has possibly got the one pole of each switch wires to to supply at one side, and ground at the other, with the wiper going to the PIC pin. One switch is 'up', and the other 'down'. Possibly they are also spring biased. What the second pole is for I haven't got a clue!. I think he is trying to do some sort of electrical gearchange, like the paddle shift on some cars. I did a system like this for a child's electric car I made a little while ago.
Best Wishes |
|
|
[email protected]
Joined: 23 Jun 2012 Posts: 22
|
|
Posted: Mon Dec 24, 2012 9:44 am |
|
|
-Usually a encoder type sensor is used for this purpose in bikes.
-I cannot use that in my bike as it costs high and also not posiible to mount.
-Yes...the code here is complicated as I have used two DPDT switches.
-This is just a part of a the main program. I have to include
codes for 4 sensors, GPS, GSM and a RTC. So the program is going to have large no. of lines.
-Initially I thought of using simple "reset" switches. Than i jumped from this thinking that the controller will not be able to scan the rise signal due to large scanning time. So I choose DPDT switches which will have one position set or reset during gear shift.
-As said I think this can be implemented using simple programming logic. But my doubt is whether the same for eg. if(input(S1) code can be used for scanning the inputs for a momentary rise signal. |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Mon Dec 24, 2012 9:54 am |
|
|
Hi,
Seriously, you need to tell us a lot more about how your system
works! You can start by telling us a bit about the mechanics of your shifter. Is
the shift pattern something like N-1-2-3-4? Can you only 'upshift' in a linear
pattern, and 'downshift' the same way? Now, what specifically do your
switches do under all circumstances? What is the output, for instance, in 'N'?
What happens to the switch outputs when you upshift from 'N' to '1', etc.?
You have to provide a lot more information about the sequence of events,
and the expected switch response to these events if you have any hope of
getting help here!
John |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Mon Dec 24, 2012 12:20 pm |
|
|
Please:-
1) Don't edit code after you've had a response. It makes nonsense of intelligent replies.
2) Learn to use the code button.
3) Provide a schematic.
4) Describe what happens to the switch-states on a gear change.
5) Provide as much other information as you can so that we can help you.
6) Explain why it is necessary to have a DPDT switch. Your code only calls for SPDT, or maybe even SPST.
At this stage, none of us have anything to work on.
Mike |
|
|
[email protected]
Joined: 23 Jun 2012 Posts: 22
|
|
Posted: Tue Dec 25, 2012 1:07 am |
|
|
Code: |
#include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=20000000)
#define S1 PIN_B1// reset switch
#define S2 PIN_B2// reset switch
#define NEUTRAL PIN_B3 // 5 LEDs
#define FIRST PIN_B4
#define SECOND PIN_B5
#define THIRD PIN_B6
#define FOURTH PIN_B7
int flag=0; //global initialization
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
while(1)
{
if (!input(S1)) //during upshift, logic level of S1 gets low
{
flag++; //gear up (neutral - 1 - 2 - 3 - 4 )
}
else if (!input(S2)) //during downshift, logic level of S2 gets low
{
flag--; //gear down (4 - 3 - 2 - 1 - neutral)
}
if(flag==0)
{
output_high(NEUTRAL);
}
else
{
output_low(NEUTRAL);
}
if(flag==1)
{
output_high(FIRST);
}
else
{
output_low(NEUTRAL);
}
if(flag==2)
{
output_high(SECOND);
}
else
{
output_low(SECOND);
}
if(flag==3)
{
output_high(THIRD);
}
else
{
output_low(THIRD);
}
if(flag==4)
{
output_high(FOURTH);
}
else
{
output_low(FOURTH);
}
}
}
|
-Now I have used simple reset switches and changed the codes.
-The bike uses a shift lever pivoted about its center.
-I am mounting one of the reset switch (S2) at the front end beneath the lever, so when downshift occurs, switch S2 is pressed.
-In similar manner I mount the reset switch (S!) at the rear end beneath the lever, so when up-shift occurs, switch S1 is pressed.
-The shift pattern is N-1-2-3-4.
-The lever returns to its initial position after a shift so a press at any switch will reset logic high to the inputs momentarily.
-This is the way I have changed
-But once the LED glows, it never turns OFF again and there is no response to inputs from S1 and S2.
-I am not sure that the global declaration is working.
-So pls check my program for global declaration and scanning of inputs. _________________ -humble request from a beginner |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Dec 25, 2012 6:09 am |
|
|
Your new code is a lot easier to understand. Easier means less errors. Congratulations.
When you switch gears, how long do you estimate the switch will be activated?
Considering all mechanics behind the manual gear shifter I guess it will be a few hundredths of milliseconds at a minimum and most likely a lot longer.
Now, looking at your code running at 20MHz, how long do you think it will take to run 1 cycle where the switch is tested and the LEDs are updated? You got a feeling what I'm hinting at?
Then another problem is that you have no prevention against overflow and underflow. Now you can switch up to the 255th gear if you want to.
Here is a stupid copy/paste error: Code: | if(flag==1)
{
output_high(FIRST);
}
else
{
output_low(NEUTRAL);
} | Change the NEUTRAL to FIRST.
Have I mentioned the problem of switch bouncing? This is a problem in all mechanical switches, no matter how expensive. On make or break the switch will bounce several times until it settles in its new position. This can take up to 20ms, an eternity for high speed processors.
By the way, 20MHz is overkill for your application. You can save 75% of processor power consumption by running at 4MHz, which is still way too fast. Less power consumption means you can use a smaller power supply and save some money. Even better, use one of the newer PIC processors with internal oscillator so you can get rid of the crystal as well (smaller PCB, cheaper PIC and even less current consumption).
Switch de-bouncing and your problem of running too fast through all the stages can be fixed combined when you change the switch detection as follows:
Detect the switch is pressed, and then to do nothing (in a loop) until the switch is released again for at least 200ms. If the switch is activated within the 200ms you assume it is switch bouncing and reset the timer counter to zero again and wait for the next 200ms of switch inactivity. |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Tue Dec 25, 2012 11:10 am |
|
|
Hi,
Frankly I don't see how this is ever going to work reliably. Since there is no
unique set of conditions for each gear, what happens if/when the mechanics
and the code loses sync? For instance a switch closure is missed, or the PIC
restarts? For that matter, what happens when the code starts running, and
the gear shift is not in the expected position?
I'm sure that OEM shift indicator systems use a more sophisticated sensing
arrangement. I'm not really sure what you'd do after the fact?
John |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Tue Dec 25, 2012 5:29 pm |
|
|
If you are using the switches to count "up" and "down" as it looks like you are, there are two problems - the first is as another pointed out, when they get out of sync - the second (which basically insures the first happens) is the switches need to be very thoroughly de-bounced or each time one closes you may get 20 or 30 counts (almost all mechanical switches bounce multiple times when they close). You may well also see bounces if you are riding on rough terrain. _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
|