Triggering 5 millisecond pulses part #1

Please try the below sketch at Freq. 1Hz,
Click here -> Wokwi Simulator

#define ainPin A0

#define compareVoltage 2.0f
#define pulseTime 50ul
#define hiAmplitude 6
#define loAmplitude 1

float input_voltage;
uint32_t pulseStartAtMs;
bool inPulse;
uint8_t Millis ;

void setup() {
  Serial.begin(115200);
  input_voltage = 0.0f;
  inPulse = false;
}

void loop() {
  int analog_value = analogRead(ainPin);
  float prevInputVoltage = input_voltage;
  input_voltage = (analog_value * 5.0) / 1023.0f;

  if (prevInputVoltage < compareVoltage && input_voltage >= compareVoltage) {
    Millis = hiAmplitude;
    inPulse = true ;
    pulseStartAtMs = millis() ;
  }

  if (inPulse && millis() - pulseStartAtMs >= pulseTime) {
    inPulse = false ;
    Millis = loAmplitude;
  }

  Serial.println(
    "Input:= " + String(input_voltage, 2)
    + ", Millis:= " + String(Millis)
    + ", Compare Voltage:= " + String(compareVoltage, 2)
  );
}
1 Like

It looks doing 5ms past the last instant when if(input_voltage >=2),

You want some state change detection logic to catch the transition to >=2. Something like:

if (input_voltage >= 2 && last_input_voltage < 2) {
...

}
...
last_input_voltage = input_voltage;

With a smooth curve, there will be only one instant where it crosses the threshold, as compared to a long interval where it is above a threshold.

An example of analog state change detection:

I modified users @microbeaut code from his WOKWI-simulation (in short WoSim)

that the code has really self-explaining names and I added comments that shall intensivly explain how it works.

I added switching IO-pin 4 for the 5 millisecond pulses.
The lines that use variable "pulsePinState" (formerly named "Millis" which makes no sense to me at all) can be deleted in the real application.
Same for function with name "printVisualisationToWokwi()"

/*
  Arduino Forum
  Topics:       Triggering 5 millisecond pulses part #1
  Category:     Using Arduino
  SubCategory:  Programming Questions
  Link:         https://forum.arduino.cc/t/triggering-5-millisecond-pulses-part-1/1135999/85
*/

const byte analogInputPin = A0;
const byte pulsePin       =  4;

#define compareVoltage 2.0f
#define pulseTime 50ul
#define switchedOn 6
#define switchedOff 1

float input_voltage;
uint32_t pulseStartAtMs;
bool sineCrossedThresholdUpwards;  // former name "inPulse";
uint8_t pulsePinState; // former name "Millis";


void setup() {
  Serial.begin(115200);
  digitalWrite(pulsePin,LOW);
  pinMode(pulsePin, OUTPUT);
  input_voltage = 0.0f;
  sineCrossedThresholdUpwards = false;
}

void loop() {
  int analog_value = analogRead(analogInputPin);

  // assign input_voltage of LAST iteration
  float prevInputVoltage = input_voltage; // let's say the value is 1.99V

  // as the ACTUAL input_voltage is assigned BELOW prevInputVoltage
  // prevInputVoltage holds the voltage of the LAST iteration
  input_voltage = (analog_value * 5.0) / 1023.0f; // let's say value is 2.01V

  // example-numbers
  //    1.99V          <     2.00V              2.01V    >=   2.00V
  if (prevInputVoltage < compareVoltage && input_voltage >= compareVoltage) {
    sineCrossedThresholdUpwards = true; // set the flag that indicates what the name says: sineCrossedThresholdUpwards
    pulsePinState = switchedOn;         // for a real IO-Pin set state = HIGH
    digitalWrite(pulsePin,HIGH);        // 5 ms-pulse starts   
    pulseStartAtMs = millis();          // store snapshot of time 
  }

  // if sinewave is rising 
  // and crossed threshold      check how much time has passed by since threshold-crossing
  if (sineCrossedThresholdUpwards && millis() - pulseStartAtMs >= pulseTime) {
    // if more time than specified in variable pulseTime HAS passed by
    sineCrossedThresholdUpwards = false ; // clear flag that indicates what the name says: sineCrossedThresholdUpwards
    pulsePinState = switchedOff;
    digitalWrite(pulsePin,LOW);           // 5 ms-pulse ends   
  }

  printVisualisationToWokwi();
}


void printVisualisationToWokwi() {   
  // serial printing ONLY used for visualisation in WOKWI
  Serial.println(
    "Input:= " + String(input_voltage, 2)
    + ", Millis:= " + String(pulsePinState)
    + ", Compare Voltage:= " + String(compareVoltage, 2)
  );
}

A question @microbeaut where did you get this sinewave-generator from?
I could create a copy of your WoSim
link Arduino Forum - Triggering 5 millisecond pulses part-better-Names - Wokwi ESP32, STM32, Arduino Simulator

The project-number deviates from your project-number
But I was unable to save modifications of your WoSim.

The modifications work online. Just saving is not possible.

Are you a paying customer of the WOKWI-simulator?
At what cost-level does WOKWI enable such special features?

best regards Stefan

1 Like

I have created myself.

No, I used to be a member.
To be a member, please find information from this link https://wokwi.com/club.

Thanks
It's working as needed.
What is the purpose of the letters on the end ?

#defin comepareVoltage 2.0f
#define pulseTime 25ul

Thanks
Great explanation

1 Like

Thank you to all participants

1 Like

"f" for variabletype float
"ul" for variabletype unsigned long
without the trailing letter the compiler would use variabletype int which could (not must) lead to odd results when calculations are done with the values

2 Likes

Toggle the Save & Down-Arrow / LockProject menu item:

image

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.