BlindAssassin111:
OK, I drew up an idea I had that might work, not 100% sure, but it seems viable. I can’t upload the drawing because the internet in my apartment sucks right now. I will have to upload while on campus tomorrow to see if it works.
https://www.dropbox.com/s/i750ik4y8aiax … 5.jpg?dl=0
I would make the diodes Schottky types, so the voltage across them is lower (0.3v) than normal diodes (0.65). And I wouldn't use pin 1 (or 0) until I ran out of other pins. They are tied to a UART you might, maybe want to use in the future.
Why isn’t the clutch solenoid used during upshifts ?
So is what I posted possible/not going to fail epically?
How would I know if a diode a Schottky diode when ordering?
The reason there is no clutch during upshift has to do with how a sequential transmission works, you just need to cut ignition during upshifts and no clutch is needed.
BlindAssassin111:
So is what I posted possible/not going to fail epically?
Nope. You might get away w/no diodes since the switch should break-before-make and so all the Arduino pin should "see" is a ground or an open circuit, but just in case ...
BlindAssassin111:
How would I know if a diode a Schottky diode when ordering?
Specify it when you search the vendor's site.
http://www.digikey.com/catalog/en/partg … iode/10636
A BAT54 would be a good choice though a BAT85 might be easier to work with (axial lead vs SMT).
Okay so I am looking at the BAT85 because of the axial leads, which is all I can use right now, but I don’t know what to pick…The forward voltage for most is very small and I thought that the internal pull-up resistors would have more voltage than what some Schottky Diodes are rated for.
So could you recommend a good one to use or just tell some specs that could help find the right one for the project?
Also I am very surprised that my idea could actually work…I was falling asleep as I drew the picture and could barely write that post…goes to show my brain likes to wait 'till the last moment to come up with ideas.
The diode is only there to block any voltage that might be on the switch pin before it get’s grounded. Ideally there should be nothing there … if your diagram is correct. If there’s 14+V for some reason, then the diode will be reversed biased and so block it from the Arduino pin. When the switch applies the ground current will flow from the Arduino 5V through it’s internal pull-up resistor to the pin and thus through the diode to ground. The Arduino pin will “see” the diode drop voltage (Vf) and since it’s a Schottky, that voltage will be small, about 0.3V. That’s comfortably below the CMOS logic low threshold (0.8V) and so the switch ground results in ~0.3V which will still produce a logic low on the pin.
Had it been a normal silicon diode the Vf would be about 0.6-0.7V, a little too close to the threshold for my likings. And that would mean a logic low is likely, but not guaranteed.
A BAT85 should be OK.
Sorry for the really late reply, I have been very busy and just now had time to actually make a reply.
I think you misunderstood what I meant by recommendations, I have looked at the BAT85 diodes, but my question was with a Vf on most around 550mV to 800mV, would that be too low of a forward voltage max? I am not sure how much actually would be put out of the pins that are set as INPUT_PULLUP, is there actually any voltage on the pins when they are connected to ground? That was what I was meaning, I was expecting a full 3.3V to be on the pins but I have never worked with it before.
On another note, I finally coded the gear indicator, which only took me 15 minutes to do.
/*#define FLIPDISPLAY*/
#include <AlphaNumeric_Driver.h>
#define NUMBER_OF_DISPLAYS 1
int SDIpin = 7;
int CLKpin = 6;
int LEpin = 5;
int OEpin = 4;
int Upshift = 12;
int Downshift = 13;
char initial = 'X';
boolean iniGear = false;
int currentGear = 5;
alphaNumeric mydisplay(SDIpin, CLKpin, LEpin, OEpin, NUMBER_OF_DISPLAYS);
void setup()
{
Serial.begin(9600); // Is this even needed?
pinMode(Upshift, INPUT_PULLUP);
pinMode(Downshift, INPUT_PULLUP);
mydisplay.print(initial);
while(iniGear == false)
{
if (Downshift == LOW)
{
currentGear--;
}
if (currentGear == 1)
{
iniGear = true;
}
}
}
void loop()
{
if (Upshift == LOW)
{
if (currentGear <= 4 && currentGear >=1)
{
currentGear++;
mydisplay.print(currentGear);
}
else
mydisplay.print(currentGear);
}
else if (Downshift == LOW)
{
if (currentGear >=2 && currentGear <=5)
{
currentGear--;
mydisplay.print(currentGear);
}
else
mydisplay.print(currentGear);
}
}
Does it seem good and actually usable? I am using the while in the setup to force the driver to downshift 4 times to get into first, at least to guarantee that they are in 1st, in order for the indicator to actually display. Other than that I am just making it display the gear and preventing it from going over 5 and below 1.
Also, for the last time, could you do a drawing showing exactly how to wire up the zener? I don’t want to screw it up and I know we can’t afford to screw things up at all. Would you be able to do it so it has the arduino in the drawing and what pins are connected, and in what manner, with no ambiguity to how it attaches, meaning not like the drawings you already posted(like the ground wire, I don’t get how the drawing is telling me how to attach it)? I know that I keep asking this but I keep forgetting by the time I actually draw it out, and I feel dumb having to ask so many times.
BlindAssassin111:
I think you misunderstood what I meant by recommendations, I have looked at the BAT85 diodes, but my question was with a Vf on most around 550mV to 800mV, would that be too low of a forward voltage max? I am not sure how much actually would be put out of the pins that are set as INPUT_PULLUP, is there actually any voltage on the pins when they are connected to ground? That was what I was meaning, I was expecting a full 3.3V to be on the pins but I have never worked with it before.
IIRC the switch applies a ground and is otherwise an open. If I was 200% sure of this then you might/maybe/possibly could wire the switch directly to the Arduino digital input pin. When that input is configured w/the internal pullup enabled, it'll "see" a HIGH when open and a LOW when grounded. The diode is there just in case there's any voltage on the supposedly open pin. It blocks any high voltage (perhaps battery voltage) from being applied directly to the Arduino and blowing it up. So now the switch is tied to the - end (cathode) of the diode. The + end (anode) of the diode is tied to the pin, which also is tied to the internal pullup resistor and thus (indirectly) to Arduino Vcc. So when the switch is open the pin still "sees" Vcc and so is a HIGH, regardless of whatever (within reason) voltage is at the switch and diode - end. The diode is not conducting any current. When a ground is applied, current now flows from Arduino
Vcc through the pullup resistor and also through the diode and finally to ground. The voltage at the pin is thus the lower Schottky Vf, well under 400 mV (at the low low current), which is under the 800 mV needed to guarantee a logic LOW. So the pin will read a LOW.
BlindAssassin111:
Does it seem good and actually usable? I am using the while in the setup to force the driver to downshift 4 times to get into first, at least to guarantee that they are in 1st, in order for the indicator to actually display. Other than that I am just making it display the gear and preventing it from going over 5 and below 1.
I'll have to look at it.
BlindAssassin111:
Also, for the last time, could you do a drawing showing exactly how to wire up the zener? I don’t want to screw it up and I know we can’t afford to screw things up at all.
Why don't you give it a shot and I'll comment on it. You'll learn this way and frankly, I'll have more drinking time ! :mrgreen:
Sorry for the late reply, been quite busy recently. I just drew up the picture of what i was thinking of how the zener is wired.
How does the code look?
IIRC the tach output consists of pulses at the battery voltage. If that’s correct then your circuit is correct. It will make a pulse at the Zener voltage, instead of the battery voltage, at pin 2 whenever the tach output pulses.
As for the code … errr … let’s start here and perhaps you can explain what you intend it to do.
while(iniGear == false)
{
if (Downshift == LOW)
{
currentGear--;
}
if (currentGear == 1)
{
iniGear = true;
}
}
The thing I see is that Downshift is a pin number and so you want to do a digitalRead(Downshift) to get the state of the pin. Also think about how fast the while() loop above runs. It will take less than 100 usec to go from top to bottom and back to the top. How long will a single (down)shift take ? How long during that single shift will the pin be LOW ? I think you meant to count the number of (down)shifts but that loop wont do it. You either need to look for a falling edge only (not the state of the pin) and decrement currentGear w/each edge or look to see that a shift has been completed before looping again (that is detect a rising edge after a falling edge).
An Uno has 2 easy to use external interrupts. I believe one is being used to count the tach pulses. I don’t know if the other is still unused. Using an ISR would be a way to count falling edges.
http://arduino.cc/en/Reference/AttachInterrupt
Lastly how sure are you that the vehicle will be in 5th gear every time the Arduino is reset and/or powered up ?
Ok, that is good that I managed to figure out the zener…now on to the code.
First, just as a reminder, I am using a Pro micro for the gear indicator, which is a separate entity to the tachometer that I was doing, just because it fits where I need it to and it runs at 3.3V which is what the alphanumeric driver runs at, so logic level shifting isn’t needed.
Okay, so now that you mention the whole “Downshift” being a pin number…I feel pretty stupid for not even realizing that I messed up that part of the code. I now have the statements in this format:
if (digitalRead(Downshift) == LOW)
and just to clarify, when you have the internal pullup enabled, when the pin connects to ground is it HIGH or LOW? and when the connection to ground is open is it HIGH or LOW? That only changes a tiny bit of the code but it would be a good thing to fix before hand.
I know that a shift takes about 100ms, which depending on the reaction time of the person shifting, should be about half of that time, so if the looping part of the code is able to complete hundreds of times before the pin changes state it should be good, but then again it would have problems because it would automatically want to either show 1 or 5 depending, because it doesn’t look for change of state just the current state. What would be the best way to code that? Seeing as I don’t know how to look for change of state at all…And because I don’t know how to look for a rising/falling edge. But yes that is what it really should be doing, because otherwise it won’t be able to accurately indicate gear.
Also the setup part of the code is just to make sure that even if the driver forgets to shift to first, or we change gear by hand while the car is off, it will guarantee that the car is in first before it will display anything helpful.
BTW I assumed from your code that when a downshift is in process, the input pin is in a LOW state. But looking at your diagram here …
https://www.dropbox.com/s/i750ik4y8aiax … 5.jpg?dl=0
… I wonder if that’s the case. It appears to me that a ground must be applied to the solenoids in order for a shift to occur. That means the normally closed (nc) switch output becomes open during the shift and the no output (to the solenoids) becomes closed and thus tied to ground. It appears then that when not shifting the nc output, tied to the Arduino, is therefore closed (hence the nc) and tied to ground. So the Arduino sees a ground most of the time and and open when shifting. An open will, if the input is configured w/it’s pull-up resistor enabled, be a HIGH.
FWIW I would not use pins 0 and 1 on an Uno for almost anything. There are already used by the Uno for communication to the USB chip. Pin 2 is an external interrupt pin as is pin 3. It would seem that if you want to count tach pulses and up and down shifts then you’d want 3 external interrupts. But only 2 are easy to use. That said there are other “pin change” interrupt pins that can be used, it just takes a little more work. Read this …
http://playground.arduino.cc/Main/PinChangeInt
Alternately there are other Arduinos with more external interrupt pins. W/o going to a MEGA, any of the 32U4 based Arduinos (Micro, SFE’s Pro Micros) have 5 (IIRC) external interrupt pins that are easy to use.
EDIT : I see you posted while I was typing this. So you have a Pro Micro (PM) for this task and so have many multiple ext interrupts. FWIW I think you could put all the code in the PM and get rid of the Uno if you wanted to.
The alphanumeric driver and the Bar graph would require too much current for the little Pro Micro to handle, so I will keep them separate for now. I will look into the attachinterupt stuff tomorrow as I am to tired to do anymore today.
BlindAssassin111:
I will look into the attachinterupt stuff tomorrow as I am to tired to do anymore today.
There are multiple ways to do what you want. My opinion is that using interrupts, given you have a PM to do the task, is the most 'elegant' way to accomplish the task. Plus it's very similar to how you count tach pulses in the Uno. So use 2 ext interrupt pins (your pick, the PM doesn't have the same "problem" w/pins 0/1 as the Uno does) ... one to count upshifts and the other pin to count downshifts. There's one problem with real life switches, that I won't go into now, that will have to be handled ...but that can come after you've got the basics of the code done.
But first … does the Arduino “see” a ground or an open during a shift ? That is, a LOW or a HIGH.
…So you know that awkward moment when you realize you said you were using something but you weren’t? Well I just did that, I am actually going to be using a Pro Mini, not the micro just because of the fact the USB on the micro has given people issues. Would that make it any harder to code or would it be worth just going to the micro?
BlindAssassin111:
Would that make it any harder to code or would it be worth just going to the micro?
No harder, it'll have 2 external interrupts like an Uno.
So…after a month of being busy and not being motivated I am back.
I have decided that I will not have the start-up sequence that forces you to downshift all the way due to the fact that at competition the car will be in neutral while in transit from the paddocks to the course, therefore the code for the number limiting would help in the fact that if the number one is displayed and you downshift to go from neutral to 1st, it will still display 1. Now the only part of the code that I am not sure how to do is the loop…What goes in there?
Here is the code so far :: (also do I need the line to start serial?)
/*#define FLIPDISPLAY*/
#include <AlphaNumeric_Driver.h>
#define NUMBER_OF_DISPLAYS 1
int SDIpin = 7;
int CLKpin = 6;
int LEpin = 5;
int OEpin = 4;
int Up = 2;
int Down = 3;
int currentGear = 1;
alphaNumeric mydisplay(SDIpin, CLKpin, LEpin, OEpin, NUMBER_OF_DISPLAYS);
void setup()
{
Serial.begin(9600); // Is this even needed?
pinMode(Up, INPUT_PULLUP);
pinMode(Down, INPUT_PULLUP);
mydisplay.print(currentGear);
attachInterrupt(0, downShift, RISING);
attachInterrupt(1, upShift, RISING);
}
void loop()
{
}
void upShift()
{
if (currentGear <= 4 && currentGear >=1)
{
currentGear++;
mydisplay.print(currentGear);
}
else
mydisplay.print(currentGear);
}
void downShift()
{
if (currentGear >=2 && currentGear <=5)
{
currentGear--;
mydisplay.print(currentGear);
}
else
mydisplay.print(currentGear);
}
After the loop is done I will have to wait until January to even begin testing, because for some reason we wait 'till the last minute to buy any electrical parts for the car…
Now the only part of the code that I am not sure how to do is the loop…What goes in there?
The way you've coded the display update into the ISRs, I'm not sure anything has to go in the *loop()*. Perhaps to debug the code before you get the display you could put a *delay(1000)* and a *Serial.println(currentGear)* in it so the up and down shifts can be simulated and seen in the serial monitor window. If you're not using the serial monitor then you don't need the *Serial.begin()* statement.
One thing I don’t see is any allowance for switch bounce, which may or may not, be a concern in your case.
http://www.pololu.com/docs/0J16/4
http://www.allaboutcircuits.com/vol_4/chpt_4/4.html
If your switches do bounce you may end up double or triple counting each shift. There are many ways to de-bounce a switch in software but in your case it might be easiest to record the time of each up- and down- shift using the millis() function. Then compare the time of each interrupt w/the time of the prior interrupt (see tutorial below) and if they’re closer in time than a human could shift, it’s a bounce and don’t change the currentGear value (ie - do nothing in the the ISR). If the difference is > than some interval, it is a shift and change the currentGear value.
http://arduino.cc/en/Reference/Millis
http://arduino.cc/en/Tutorial/BlinkWithoutDelay
BTW since the currentGear value is changed in a interrupt you probably should declare it as a volatile.
http://arduino.cc/en/Reference/Volatile
Is there a way to save the average time to do an upshift and downshift to the arduino so that it has it for reference? That way I can just run the system for a little bit, have the data, and calculate the average time, and hard coding that reference and then compare that way and via comparison to the last time?
I will have to do a lot of debug once I actually get all of the parts in, we just ordered the pro mini and nothing else so I can’t even program it yet, and since I don’t have the other parts for the system I have no way of even testing to make sure everything works correctly.
Edit: I knew that it currentGear was supposed to be a volatile int I just didn’t notice I had forgotten to type volatile in the code…I felt stupid when you pointed that out
I don’t think you want an average time between shifts, you want the quickest time. I suppose you could write some separate test code to spit out shift times and the go through a series of “quick shift” tests.
As for testing … if you have the Arduino and a PC you could cobble up a couple of push button switches to simulate the transmission.
I was mainly wanting to just use the average time to get a ball park for the program so it knows that within parameters of time that I set via hard code and/or via the last shift time.
Edit: And because the judges at competition would like the fact that I tested that system to figure out the best way to make sure it functions how I want it to. Helps get us design points. :lol: