bobnova 59 Posted August 14, 2014 Share Posted August 14, 2014 I definitely recommend laying your hands on an oscilloscope of some sort. It doesn't have to be an expensive, "good", one. A $65ish DSO201 handheld thing is fine, or a similarly priced USB scope. It may not be especially accurate, but it'll be decently consistent and that's good enough for a lot of work. Another alternative is to buy a used standalone scope, mine came from the university of washington and appears to have last been calibrated in 1977. Despite that, it works great and is surprisingly accurate and precise. It was $35 + $35 of shipping. I've never used the sound card method, but I've heard they're not bad at all. I would grab a cheap sound card of some sort to abuse rather than using your motherboard's on board card or an expensive "nice" card, just because it would be unfortunate to blow up something you cared about. I've used mine for an incredible variety of things, I can't imagine not having one now. (EDIT: On consistent vs accurate in my mind. When I say accurate I am thinking: A 5.0000v signal is read as 5.0000+/- a small amount. When I think consistent I am thinking: A 5.0000v signal is read as 4.8588 (or something else not 5.0000), but it's read that way every single time. Accurate to itself, essentially) abecedarian 1 Quote Link to post Share on other sites
abecedarian 330 Posted August 15, 2014 Author Share Posted August 15, 2014 Again, thanks to all for the advice and ideas. When the ECU spins off to its own board, this will be immensely helpful. Thanks! Quote Link to post Share on other sites
abecedarian 330 Posted September 3, 2014 Author Share Posted September 3, 2014 After much distraction, deliberation and such, I found some more time to devote to this. I'm dealing with periods, or frequencies if you will, which are actually quite low: 200 RPM = 3.3 Hz, 1000 RPM = 16.6 Hz and 10000 RPM = 166.6 Hz. Given I have 32 'teeth' on the wheel, the crankshaft trigger signal is 106.6 Hz, 533.3 Hz and 5333.3 Hz, respectively. So, all crankshaft speeds from cranking, around 400 RPM, to redline, approximately 10000-11000 RPM, are audible frequencies. So comes the epiphany: why not use Energia's "tone" function? I can attach an interrupt to the tone output pin on either rising or falling edge, increment a counter with each event, and do a modulus calculation trigger the cam output signal: (counter % 64) == 0. Then it's generating 1 cam signal for every 64 simulated crank trigger signals. The serial output doesn't appear to glitch anything at all but I still don't have a 'scope and haven't dove into the audio 'scope thing yet so can't verify glitches do not occur. #define crankTrigger P2_1 #define camTrigger P2_2 #define numberOfTeeth 32 uint8_t toothCount = 0; uint32_t toothFreq = 0; uint16_t revolutionsPerSecond = 0; void cam() { digitalWrite(camTrigger, (toothCount++ % 64) == 0); } void setup() { Serial.begin(9600); pinMode(crankTrigger, OUTPUT); digitalWrite(crankTrigger, LOW); attachInterrupt(crankTrigger, cam, FALLING); pinMode(camTrigger, OUTPUT); digitalWrite(camTrigger, LOW); tone(crankTrigger,toothFreq); } void loop() { while (revolutionsPerSecond < 170) { toothFreq = revolutionsPerSecond * numberOfTeeth; Serial.println(String("Rev/Sec:" + String(revolutionsPerSecond) + " Teeth/Sec:" + String(toothFreq))); tone(crankTrigger, toothFreq); revolutionsPerSecond++; delay(50); } tone(crankTrigger, 0); while (1); }I think I'm further saved by the fact that 32 teeth goes into 256 evenly so overflowing the tooth count variable (byte sized) doesn't create any issue regarding calculating when to roll over the tooth count to zero. Quote Link to post Share on other sites
David Bender 28 Posted September 4, 2014 Share Posted September 4, 2014 Are you actually getting any output? P2_1 is associated with TimerA1.1. However, Energia's tone() function only works with TimerA0. Choose a different pin that associates with a TimerA0.x output. https://github.com/energia/Energia/blob/master/hardware/msp430/cores/msp430/Tone.cpp Quote Link to post Share on other sites
abecedarian 330 Posted September 4, 2014 Author Share Posted September 4, 2014 @@David Bender - I actually am getting output. I pulled the jumpers off the LED's and ran jumper wires over to the LED's- P2_1 to red, P2_2 to green. If I set the tone frequency to 32, the red led flashes, albeit at a fast rate and the green led is flashing once every two seconds. I'm currently doing a little modifications to the code, added a 'tachometer' output to P2_3, and that one flashes once per second. I also have the MSP simultaneously sending the data to the serial terminal window and to an I2C LCD display as well. The code finishes up setting tone to 32Hz and entering an infinite loop. Here's the current code: #include <LiquidCrystal_I2C.h> /* LiquidCrystal_I2C library from: http://hmario.home.xs4all.nl/arduino/LiquidCrystal_I2C/ */ LiquidCrystal_I2C lcd(0x20,20,4); // set the LCD address to 0x20 for a 20 chars and 4 line display #define crankTrigger P2_1 #define camTrigger P2_2 #define tachOut P2_3 #define numberOfTeeth 32 uint8_t toothCount = 0; uint32_t toothFreq = 0; uint16_t revolutionsPerSecond = 0; String rps; String tps; void crank() { digitalWrite(camTrigger, (toothCount % (numberOfTeeth * 2)) == 0); digitalWrite(tachOut, (toothCount % numberOfTeeth) == 0); toothCount++; } void setup() { Serial.begin(9600); lcd.init(); lcd.backlight(); pinMode(crankTrigger, OUTPUT); digitalWrite(crankTrigger, LOW); pinMode(tachOut, OUTPUT); digitalWrite(tachOut, LOW); pinMode(camTrigger, OUTPUT); digitalWrite(camTrigger, LOW); attachInterrupt(crankTrigger, crank, FALLING); tone(crankTrigger, toothFreq); } void loop() { Serial.println("R/s T/s"); lcd.home(); lcd.print("Rev/Sec:"); lcd.setCursor(0,1); lcd.print("Teeth/Sec:"); while (revolutionsPerSecond < 170) { rps = String(revolutionsPerSecond); toothFreq = revolutionsPerSecond * numberOfTeeth; tps = String(toothFreq); Serial.println(String(rps) + " " + String(tps)); lcd.setCursor(12,0); lcd.print(rps); lcd.setCursor(12,1); lcd.print(tps); tone(crankTrigger, toothFreq); revolutionsPerSecond++; delay(50); } tone(crankTrigger, 32); while (1); } Quote Link to post Share on other sites
David Bender 28 Posted September 4, 2014 Share Posted September 4, 2014 Doh, I looked at Tone.cpp again and now it makes sense. I had thought Energia would set up the Timer output directly but it actually toggles the POUT in the interrupt handler. I would expect to see a few microseconds of jitter between the cam pulse and the crankshaft pulse that triggered it, but should be OK. Quote Link to post Share on other sites
abecedarian 330 Posted September 4, 2014 Author Share Posted September 4, 2014 Thank goodness. I was starting to think my LP was possessed. And I'm not too worried about jitter between the crank and cam signals so long as the cam signal is output after 64 crank signals. I'm actually going to tweak on the code a bit to allow offsetting the cam signal an arbitrary number of 'teeth' in either direction. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.