I have a model of a 2 stroke engine to show my students how it works.
I have a solenoid which operates a valve at a certain degree of the crankshaft rotation.
If the engine stops with the solenoid HIGH it over heats and melts the plastic.
I have an Absolute Rotary Encoder telling the Mega where the crank is, and over 100 Neopixels flashing at certain positions, so I can't use delay()
I've chopped out most of the code with the Neopixels (over 5100 lines of code)
I can use the "blink without delay" but that just "blinks" the solenoid when it is HIGH.
const int PIN_DATA = 10;
const int PIN_CS = 9;
const int PIN_CLOCK = 8;
// The Time the Solenoid will stay on if the engine stops when Solenoid HIGH
// This will overheat the Solenoid and melt the plastic
//int SolenoidState = LOW;
const int Solenoid = 7; // Solenoid Pin
int SolenoidState = LOW;
long interval = 1000; // 1 second
long unsigned lastTime = 0; // will store last time Solenoid was updated
int Timing = 0; // variable to store the 'fine tuning' of the NeoPixels
// or you could just turn the encoder / crankshaft pulley
#define TIMING_PIN A1 // POT for adjusting NeoPixels timing
#define SPEEDPIN A5 // POT for adjusting Motor Speed
// These pins are hardwired in the motor shield
const int MotorDir = 12; // output pin for the Motor Direction
const int MotorSpeed = 3; // output pin for the Motor Speed
int MotorPot = 0; // variable to store the value coming from the Motor POT
int TimingPot = 0; // variable to store the value coming from the Timing POT
void setup()
{
Serial.begin(9600);
pinMode(PIN_CS, OUTPUT);
pinMode(PIN_CLOCK, OUTPUT);
pinMode(PIN_DATA, INPUT);
pinMode (MotorDir, OUTPUT);
pinMode (TimingPot, INPUT);
pinMode (MotorPot, INPUT);
pinMode (Solenoid, OUTPUT);
digitalWrite(PIN_CLOCK, HIGH);
digitalWrite(PIN_CS, LOW);
}
void loop()
{
// This bit for the speed control for the Electric Motor
digitalWrite(MotorDir, HIGH); // Motor direction
int SpeedPin = analogRead(SPEEDPIN);
int Speed = map(SpeedPin,0,1024,0,255);
analogWrite (MotorSpeed, Speed);
// This bit is for the Absolute Rotary Encoder
digitalWrite(PIN_CS, HIGH);
digitalWrite(PIN_CS, LOW);
int pos = 0;
for (int i=0; i<10; i++)
{
digitalWrite(PIN_CLOCK, LOW);
digitalWrite(PIN_CLOCK, HIGH);
byte b = digitalRead(PIN_DATA) == HIGH ? 1 : 0;
pos += b * pow(2, 10-(i+1));
}
for (int i=0; i<6; i++)
{
digitalWrite(PIN_CLOCK, LOW);
digitalWrite(PIN_CLOCK, HIGH);
}
digitalWrite(PIN_CLOCK, LOW);
digitalWrite(PIN_CLOCK, HIGH);
int EncoderAngle = map(pos,0,1024, 0, 360);
// This bit is to adjust the timing and
// keep the angle less than 360 degrees
int AdjAngle = analogRead(TIMING_PIN);
AdjAngle = map(AdjAngle, 0, 1024, 0, 360);
int Angle = (AdjAngle + EncoderAngle);
if (Angle >= 360) {
(Angle -= 360);
}
//Serial.print(" Adjustment Angle ");
//Serial.print(AdjAngle);
//Serial.print(" Encoder Angle ");
//Serial.print(EncoderAngle);
// This bit for the solenoid on the Vacuum Port Cylinder
if (Angle >160 && Angle <= 280)
{
digitalWrite (Solenoid, HIGH);
if(millis()- lastTime >= interval)
{
lastTime = millis();
if (Solenoid == HIGH)
SolenoidState = LOW;
else
SolenoidState = LOW;
digitalWrite(Solenoid, SolenoidState);
}
}
else
(digitalWrite (Solenoid, LOW));
/* if (Angle >160 && Angle <= 280)
{
if(currentMillis + interval > millis())
{
if (Solenoid == HIGH)
SolenoidState = LOW;
else
SolenoidState = LOW;
digitalWrite(Solenoid, SolenoidState);
}
}
*/
Serial.print(" Angle ");
Serial.print(Angle);
Serial.print(" Millis ");
Serial.print(millis());
Serial.print(" Last Time ");
Serial.print (lastTime);
//Serial.print(" previousMillis ");
//Serial.print (previousMillis);
Serial.print( " Solenoid " );
Serial.println (digitalRead (Solenoid));
}
The bit I'm having trouble with is while the code is in the first "if statemsnt"
// This bit for the solenoid on the Vacuum Port Cylinder
if (Angle >160 && Angle <= 280)
{
digitalWrite (Solenoid, HIGH);
if(millis()- lastTime >= interval)
{
lastTime = millis();
if (Solenoid == HIGH)
SolenoidState = LOW;
else
SolenoidState = LOW;
digitalWrite(Solenoid, SolenoidState);
}
}
else
(digitalWrite (Solenoid, LOW));
/* if (Angle >160 && Angle <= 280)
{
if(currentMillis + interval > millis())
{
if (Solenoid == HIGH)
SolenoidState = LOW;
else
SolenoidState = LOW;
digitalWrite(Solenoid, SolenoidState);
}
}
*/
I've tried all sorts of various codes and even a separate "void", but I'm still at a loss.
Thanks in advance
Gerry