Injector pulsing project, need a little help with code.

Hello all. I am building a little project using an Uno and needed a little help with the code. The goal is to have it setup where i can generate a square wave, that I can adjust the Duty and Frequency, using two pots. The Frequency range i’m looking to generate is 1Hz to 200Hz (displayed as RPM, 60-12,000), and a Duty of 0-100%. I’m using a serial 16X2 display to display the data, I would also like to display “High” time in MS X.XX. With the code I’m using currently, I can adjust the Duty with a pot, but can only change the Frequency by adjusting the sketch and loading it. I also have not figured out how to display the on time in MS. I’ll attach the code that I’m using currently. Thank you for any help in advance!

Allen

 #include <LiquidCrystal_I2C.h>
  #include <PWM.h>
  int32_t frequency = 20;
  LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 

  void setup()  

{

  InitTimersSafe ();
  bool success = SetPinFrequencySafe(9, frequency);
  if (success) {
  pinMode (13, OUTPUT);
  digitalWrite (13, HIGH);
  
}
  
 // Serial.begin(9600); 
 //Serial.println();
  lcd.begin(16, 2);   
  lcd.clear ();
  pinMode (A1,INPUT);
  pinMode (A2,INPUT);
  pinMode (9, OUTPUT);
  
{
  
  //lcd.backlight();
  //delay(250);
  //lcd.noBacklight();
  //delay(250);
  
}
  
  //lcd.backlight();   
  //lcd.setCursor(0,0);
  //lcd.print("   Sup Bitches");
  //delay(1000);
  //lcd.setCursor(0,1);
  //lcd.print("Ankle Biters 2.0");
  //delay(2000);  
  //lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("RPM   DUTY   MS");
 
}

  void loop()  

{
    
  int potDuty = analogRead (A1);
  int potRpm = analogRead (A2);  
  int duty = map(potDuty ,0, 1022, 0,100);
  int rpm = map (potRpm ,0, 1022, 10, 200);  
  Serial.println("DUTY");
  Serial.println(duty);
  Serial.println("RPM");
  Serial.println(frequency * 60);
  lcd.setCursor(0, 1);
  lcd.print(F("                "));
  lcd.setCursor(7,1);
  lcd.print(duty);  
  lcd.setCursor(0,1);
  lcd.print(frequency * 60);
  pwmWrite (9, potDuty / 4);
  delay (75);

}

Lets get rid of the delay(75)
and do something different to keep from cycling the display so fast

I am not able to test your code but this may be where the problem is and if nothing else allows you to have better code :slight_smile:

#include <LiquidCrystal_I2C.h>
#include <PWM.h>
int32_t frequency = 20;
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


static unsigned long Timer;


void setup()

{

  InitTimersSafe ();
  bool success = SetPinFrequencySafe(9, frequency);
  if (success) {
    pinMode (13, OUTPUT);
    digitalWrite (13, HIGH);

  }

  // Serial.begin(9600);
  //Serial.println();
  lcd.begin(16, 2);
  lcd.clear ();
  pinMode (A1, INPUT);
  pinMode (A2, INPUT);
  pinMode (9, OUTPUT);

  {

    //lcd.backlight();
    //delay(250);
    //lcd.noBacklight();
    //delay(250);

  }

  //lcd.backlight();
  //lcd.setCursor(0,0);
  //lcd.print("   Sup Bitches");
  //delay(1000);
  //lcd.setCursor(0,1);
  //lcd.print("Ankle Biters 2.0");
  //delay(2000);
  //lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("RPM   DUTY   MS");

  Timer = millis() + 1000;  // initial setup for the display timer


}


void loop()\\
{
  int potDuty = analogRead (A1);
  int potRpm = analogRead (A2);
  int duty = map(potDuty , 0, 1022, 0, 100);
  int rpm = map (potRpm , 0, 1022, 10, 200);
  pwmWrite (9, potDuty / 4);   // now the change happens instantly no delays!!!

  if ( (long)( millis() - Timer ) >= 0) // but we don't kill the output of the Serial and lcd by trying to run the code to often
  { // millis is now later than my 'next' time
    Display();
    Timer += 300;  // do it again X miliseconds later
  }
}

void Display() {
  Serial.println("DUTY");
  Serial.println(duty);
  Serial.println("RPM");
  Serial.println(frequency * 60);
  lcd.setCursor(0, 1);
  lcd.print(F("                "));
  lcd.setCursor(7, 1);
  lcd.print(duty);
  lcd.setCursor(0, 1);
  lcd.print(frequency * 60);

}

zhomeslice:
Lets get rid of the delay(75)
and do something different to keep from cycling the display so fast

I am not able to test your code but this may be where the problem is and if nothing else allows you to have better code :slight_smile:

Thank you for the advise. It didn’t like that code for some reason though. I don’t know enough about code to fix it though. This was the message.

Arduino: 1.6.8 (Windows 10), Board: “Arduino/Genuino Uno”

C:\Users\allen\Documents\Arduino\testing\testing.ino: In function ‘void Display()’:

testing:75: error: ‘duty’ was not declared in this scope

Serial.println(duty);

^

exit status 1
‘duty’ was not declared in this scope

This report would have more information with
“Show verbose output during compilation”
option enabled in File → Preferences.

I declared the variables in a global scope
with this line:
int potDuty, potRpm, duty, rpm;

Now every function in this small program can read the Values “declared everywhere” :slight_smile:
in big programs this is dangerous because the variable could be used for other things but for us it is not an issue and just fine :slight_smile:

#include <LiquidCrystal_I2C.h>
#include <PWM.h>
int32_t frequency = 20;
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


static unsigned long Timer;
int potDuty, potRpm, duty, rpm;


void setup()

{

  InitTimersSafe ();
  bool success = SetPinFrequencySafe(9, frequency);
  if (success) {
    pinMode (13, OUTPUT);
    digitalWrite (13, HIGH);

  }

  // Serial.begin(9600);
  //Serial.println();
  lcd.begin(16, 2);
  lcd.clear ();
  pinMode (A1, INPUT);
  pinMode (A2, INPUT);
  pinMode (9, OUTPUT);

  {

    //lcd.backlight();
    //delay(250);
    //lcd.noBacklight();
    //delay(250);

  }

  //lcd.backlight();
  //lcd.setCursor(0,0);
  //lcd.print("   Sup Bitches");
  //delay(1000);
  //lcd.setCursor(0,1);
  //lcd.print("Ankle Biters 2.0");
  //delay(2000);
  //lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("RPM   DUTY   MS");

  Timer = millis() + 1000;  // initial setup for the display timer


}


void loop()\\
{
  potDuty = analogRead (A1);
  potRpm = analogRead (A2);
  duty = map(potDuty , 0, 1022, 0, 100);
  rpm = map (potRpm , 0, 1022, 10, 200);
  pwmWrite (9, potDuty / 4);   // now the change happens instantly no delays!!!

  if ( (long)( millis() - Timer ) >= 0) // but we don't kill the output of the Serial and lcd by trying to run the code to often
  { // millis is now later than my 'next' time
    Display();
    Timer += 300;  // do it again X miliseconds later
  }
}

void Display() {
  Serial.println("DUTY");
  Serial.println(duty);
  Serial.println("RPM");
  Serial.println(frequency * 60);
  lcd.setCursor(0, 1);
  lcd.print(F("                "));
  lcd.setCursor(7, 1);
  lcd.print(duty);
  lcd.setCursor(0, 1);
  lcd.print(frequency * 60);

}

Thank you for the help, it loaded this time. The display doesn't flicker as bad. I still need some help with being able to adjust the frequency with a pot, and display the high time of the output. I don't know if this sketch is capable of this. I've been searching for one that does variable frequency and duty, but have had no luck.

The more I read, the more I realize this my be an impossible task (for my skill level). Is there maybe some way i can scroll through a series of frequencys, using a push button, instead of using a pot?