Go Down

Topic: Toy kitchen stove simulation - slow PWM (Read 811 times) previous topic - next topic

RustSPb

Hi everybody,

New to arduino and programming. Upgrading Barbies kitchen and want to simulate IR stove - with minimum control - off, with maximum - continuosly lit, in between - PWM with variable DC and Frequency abt 0.2 Hz (5 sec period). Also there are 2 hotplates and one oven - any chance they can work simultaneously?
I was looking for for similar solutions ready to use, but so far without success - please give me ideas! Thanks in advance!!!

avr_fred

Why do you believe PWM at 0.2 Hz is needed to simulate a stove burner glow?

DVDdoug

 

Quote
Also there are 2 hotplates and one oven - any chance they can work simultaneously?
Yes, the Arduino Uno has 6 PWM outputs and they each can have their own PWM value.

If you want to control the brightness with pots, of course you'll need to use 3 analog inputs for that.

Wawa

#3
Feb 13, 2018, 10:12 pm Last Edit: Feb 14, 2018, 05:04 am by Wawa
Untested.
Code: [Select]
unsigned long stepTime = 20; // dim speed
unsigned long currentMillis, prevLed1Millis, prevLed2Millis, prevLed3Millis;
const byte pot1Pin = A0, pot2Pin = A1, pot3Pin = A2; // the three pot pins
const byte led1Pin = 9, led2Pin = 10, led3Pin = 11; // the three LED pins
int pot1Value, pot2Value, pot3Value;
int led1Value, led2Value, led3Value;

void setup() {
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
}

void loop() {
  currentMillis = millis(); // update with every loop
  pot1Value = analogRead(pot1Pin);
  if (pot1Value != led1Value && currentMillis - prevLed1Millis >= stepTime) { // if not the same, and time is up
    if (pot1Value > led1Value)led1Value++; // if pot is more, add to led value
    else(led1Value--); // if less, subtract
    analogWrite(led1Pin, led1Value >> 2); // write result to LED
    prevLed1Millis = millis(); // update
  }
  pot2Value = analogRead(pot2Pin);
  if (analogRead(pot2Pin) != led2Value && currentMillis - prevLed2Millis >= stepTime) {
    if (pot2Value > led2Value)led2Value++;
    else(led2Value--);
    analogWrite(led2Pin, led2Value >> 2);
    prevLed2Millis = millis();
  }
  pot3Value = analogRead(pot3Pin);
  if (analogRead(pot3Pin) != led3Value && currentMillis - prevLed3Millis >= stepTime) {
    if (pot3Value > led3Value)led3Value++;
    else(led3Value--);
    analogWrite(led3Pin, led3Value >> 2);
    prevLed3Millis = millis();
  }
}

Ken..

RustSPb

Why do you believe PWM at 0.2 Hz is needed to simulate a stove burner glow?
Hi Fred!

I want to simulate the way my real stove is working: it turns on and off for short or prolonged time with ptriod of abt 5-10 sec, depending of power set.

Wawa

We understand you want to slowly change the PWM value (dimming), not the actual PWM frequency.
Leo..

RustSPb

Yes, the Arduino Uno has 6 PWM outputs and they each can have their own PWM value.

If you want to control the brightness with pots, of course you'll need to use 3 analog inputs for that.
I don't want to control brightness. I want it full lit say 1 sec of 5 at low setting and pro rata 4 of 5 sec up to full lit, when I turn power pot.

Also i plan to use Pro Mini in final project.

RustSPb

#7
Feb 14, 2018, 04:01 am Last Edit: Feb 14, 2018, 05:30 am by RustSPb
We understand you want to slowly change the PWM value (dimming), not the actual PWM frequency.
Leo..
Hi Wawa,

Thank you for the code - first part is definitly works. But second part - and its most difficult for me - as yoy sad - just dimming leds. This is my mistake - I mislead you guys with PWM, but in fact the process I need is very slow PWM like. So as I feel - after reading pot value shoul be mapped from 0 to full cycle length (5 sec not strict) and led shold be lit to corresponding number of mills. Something like this.

I need something like this, but withiut delay:

Code: [Select]
pot1Value = analogRead(pot1Pin);
  pot1Value = map(pot1Value, 0, 1023, 0, 5000);
  digitalWrite(led1Pin, HIGH);
  delay (pot1Value);
  digitalWrite(led1Pin, LOW);
  delay (5000 - pot1Value);



This is not full project - some other functions are planned for MW, lights kettle etc, therefore would be great if full period will be easy to adjust.


wvmarle

That we don't call PWM. That's called blinking.

See "blink without delay" on how to do it for a single LED without blocking, you can easily expand that to multiple LEDs.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

Wawa

If I understand this correctly, you want to fade a LED to max brightness, but the fade time has to be controlled with a pot. When the stove knob is on low, the fade-in time should be long (but to max brightness), and when the knob is on full, the fade-in time to max brightness should be short.
Try this. It also has a (fixed) fade-out time.
Make sure you have no other delays (or slow serial printing) in the rest of your code.
Leo..
Code: [Select]
const int led1ShortFadeValue = 10, led1LongFadeValue = 100; // adjust times to suit
const int led2ShortFadeValue = 10, led2LongFadeValue = 100;
const int led3ShortFadeValue = 10, led3LongFadeValue = 100;
unsigned long led1Time, led2Time, led3Time;
unsigned long currentMillis, prevLed1Millis, prevLed2Millis, prevLed3Millis, FadeOutTime = 10;
const byte pot1Pin = A0, pot2Pin = A1, pot3Pin = A2; // the three pot pins
const byte led1Pin = 9, led2Pin = 10, led3Pin = 11; // the three LED pins
int pot1Value, pot2Value, pot3Value;
int led1Value, led2Value, led3Value;
byte threshold = 50; // pot off threshold

void setup() {
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
}

void loop() {
  currentMillis = millis(); // update with every loop
  pot1Value = analogRead(pot1Pin); // read pot
  led1Time = map (pot1Value, threshold, 1023, led1LongFadeValue, led1ShortFadeValue); // map potvalue to fadetime values
  led1Time = min(led1Time, led1LongFadeValue); // constrain, pot output not lower than that value
  if (pot1Value > threshold) { // if stove is turned on
    if (led1Value < 255 && currentMillis - prevLed1Millis >= led1Time) {
      led1Value++; // increase brightness one step
      analogWrite(led1Pin, led1Value); // write to LED
      prevLed1Millis = millis(); // update
    }
  } else { // if stove is turned off
    if (led1Value > 0 && currentMillis - prevLed1Millis >= FadeOutTime) {
      led1Value--; // decrease brightness one step
      analogWrite(led1Pin, led1Value); // write to LED
      prevLed1Millis = millis(); // update
    }
  }
  pot2Value = analogRead(pot2Pin);
  led2Time = map (pot2Value, threshold, 1023, led2LongFadeValue, led2ShortFadeValue);
  led2Time = min(led2Time, led2LongFadeValue);
  if (pot2Value > threshold) {
    if (led2Value < 255 && currentMillis - prevLed2Millis >= led2Time) {
      led2Value++;
      analogWrite(led2Pin, led2Value);
      prevLed2Millis = millis();
    }
  } else {
    if (led2Value > 0 && currentMillis - prevLed2Millis >= FadeOutTime) {
      led2Value--;
      analogWrite(led2Pin, led2Value);
      prevLed2Millis = millis();
    }
  }
  pot3Value = analogRead(pot3Pin);
  led3Time = map (pot3Value, threshold, 1023, led3LongFadeValue, led3ShortFadeValue);
  led3Time = min(led3Time, led3LongFadeValue); 
  if (pot3Value > threshold) {
    if (led3Value < 255 && currentMillis - prevLed3Millis >= led3Time) {
      led3Value++;
      analogWrite(led3Pin, led3Value);
      prevLed3Millis = millis();
    }
  } else {
    if (led3Value > 0 && currentMillis - prevLed3Millis >= FadeOutTime) {
      led3Value--;
      analogWrite(led3Pin, led3Value);
      prevLed3Millis = millis();
    }
  }   
}

RustSPb

Many thanks Wawa for new code, appreciate your help indeed.
This is not what I meant, but now I'm thinking to use it for oven with slow heating up and cooling.

For what I meant I managed to write on basis "BlinkWithoutDelay" following code, which working (for one LED so far) - please have a look if it can be optimized anyway.

Code: [Select]



const int led1Pin =  13;      // the number of the LED pin
const byte pot1Pin = A0;
const long interval = 5000;           // interval at which to blink (milliseconds)

int led1State = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
long Led1On = 0;
int pot1Value;

void setup() {
  // set the digital pin as output:
  pinMode(led1Pin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  unsigned long currentMillis = millis();
 
  pot1Value = analogRead(pot1Pin); // read pot
  Led1On = map(pot1Value, 0, 1023, 0, interval); // map pot to interval
  if (currentMillis - previousMillis >= Led1On) led1State = LOW; // unlit hot plate if time came
  if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis;// Start new interval
  if (Led1On > 10) led1State = HIGH; } // lit hot plate in begining of new intereval if switch is on
 
     // set the LED with the ledState of the variable:
    digitalWrite(led1Pin, led1State);
 
}

wvmarle

Lots of comments on style.
1) variable names: use descriptive names. Not led1 but hotPlateLed, same for pot1 and more such names. Makes it much easier to remember what is what.
2) start newline after a { and place very } on its own line. Otherwise it's very hard to follow what belongs to what.
3) use informative comments, remove superfluous and obvious ones.

So your code becomes (I didn't change the names - I did needed the help of the IDE to untangle it):
Code: [Select]

void loop() {
  unsigned long currentMillis = millis();
  pot1Value = analogRead(pot1Pin);
  Led1On = map(pot1Value, 0, 1023, 0, interval);
  if (currentMillis - previousMillis >= Led1On) {
    led1State = LOW;
  }
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis; // Start new interval
    if (Led1On > 10) {
      led1State = HIGH;
    }
  }
  digitalWrite(led1Pin, led1State);
}


And I still don't really understand what's supposed to be going on here with the LED...
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

RustSPb

#12
Feb 16, 2018, 10:50 am Last Edit: Feb 16, 2018, 11:12 am by RustSPb
Thanx Wawa and wvmarle for your valuable advices!

The Hot Plate Led is:
- off, when pot on 0 or close to 0
- 1 sec on and 4 sec off, when pot is on 20% power
...
- 3 sec on and 2 sec off, when pot is on 60% power
...
- constantly lit, when pot is on 100% power

I'm currently working of full project code, basing on "SeveralThingsAtTheSameTime" example in begining of this section, which includes:
- hot plates control as above
- oven control as above or using your second code
- MW Oven control - when button is pressed - the chamber is lit, plate starts rotating and countdown starts on 7seg indicator from 9 to 0, then all stops and and beep sounds.

Additional functions planned (though non-arduino related, but to give ideas to any possible followers:
- reed switch controlled kettle giving sound effect of boiling and whistling once placed on plate, using sound recording / playback board
- round-running water from tap, using small pump and reservoir
- main switch, also controlling spot lights
- clock
- power outlets for possible additional appliances (blender etc.)

And I came to another question or, to be honest, questions:

- I plan to use Pro Mini, but testing everything on Uno - any difference / problem?
- since I already run out of pins with 7seg - can I use also pins 0 and 1 and any restrictions for same?
- alternatively, I can use analog input pin for button input - is there any "standard solution" for same?
- how to make PWM for MW motor without stopping other processes? "Blink" motor?
- same as above for "beeping"?

Also I will appreciate any comments / suggestions from everybody, who came across regarding full project or any part of it.

wvmarle

- I plan to use Pro Mini, but testing everything on Uno - any difference / problem?
No - other than the power supply. The Mini has a much smaller regulator so can't handle high voltages well. Best powered on 5V, e.g. a mobile phone adapter. Same can be used for the LEDs.

Quote
- since I already run out of pins with 7seg - can I use also pins 0 and 1 and any restrictions for same?
Yes, can use; but you'll lose the Serial debugging as those are the Tx and Rx pins.

Quote
- alternatively, I can use analog input pin for button input - is there any "standard solution" for same?
All analog pins (except A6 and A7 - available on the Pro Mini but not the Uno) can act as digital pin just fine, so can be used as digital input, digital output, and analog input. A6 and A7 are analog input only. A4 and A5 are also used by I2C - which may come in play if you start working with port expanders.

For your project it may make sense to add a second Arduino; after all the processes don't depend on one another so no need to communicate between them.

Quote
- how to make PWM for MW motor without stopping other processes? "Blink" motor?
Use analogWrite() on a PWM enabled pin (check the manual).

Quote
- same as above for "beeping"?
Use the tone() and noTone() functions.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

RustSPb


Thanks again wvmarle for great help! Now I can finalize project!
Good news about A0-A4! How to address them in code:

const byte LedPin = A4;
pinMode(A4, OUTPUT);
digitalWrite(A4, HIGH); ?

I prefer to continue with one, partly due to space restriction within furniture, partly to learn more about arduino and combining processes.


Meahwhile I stuck a bit with switch case function - here is part of my code controlling microwave:

Code: [Select]
void readMWButton() {

     // this only reads the button state after the button interval has elapsed
     //  this avoids multiple flashes if the button bounces
     // every time the button is pressed it changes buttonLed_State causing the Led to go on or off
     // Notice that there is no need to synchronize this use of millis() with the flashing Leds
 
 if (millis() - previousMWButtonMillis >= MWButtonInterval) {

   if (digitalRead(MWButtonPin) == HIGH) {
     MWOn = true;            // switching on MW oven
     MWSwitchOnMillis = millis(); // fixing MW on time
     // Switch on MW light
     // Switch on MW motor
   
     previousMWButtonMillis += MWButtonInterval;
   }
 }

}

//========================================

void UpdateMWState () {

  if (MWOn = true) {
       
    currentMillis = millis();
    MWMillisOn = currentMillis - MWSwitchOnMillis;
       
    switch (MWMillisOn) {
     
     case MWMillisOn < 1000:
       digitalWrite(pinA, B0);
       digitalWrite(pinB, B0);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B0);    //9
       digitalWrite(pinE, B1);
       digitalWrite(pinF, B0);
       digitalWrite(pinG, B0);
     break;

     case MWMillisOn < 2000:
       digitalWrite(pinA, B0);
       digitalWrite(pinB, B0);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B0);    //8
       digitalWrite(pinE, B0);
       digitalWrite(pinF, B0);
       digitalWrite(pinG, B0);
     break;
     
     case MWMillisOn < 3000:
       digitalWrite(pinA, B0);
       digitalWrite(pinB, B0);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B1);    //7
       digitalWrite(pinE, B1);
       digitalWrite(pinF, B1);
       digitalWrite(pinG, B1);
     break;
     
     case MWMillisOn < 4000:
       digitalWrite(pinA, B0);
       digitalWrite(pinB, B1);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B0);    //6
       digitalWrite(pinE, B0);
       digitalWrite(pinF, B0);
       digitalWrite(pinG, B0);
     break;
     
     case MWMillisOn < 5000:
       digitalWrite(pinA, B0);
       digitalWrite(pinB, B1);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B0);    //5
       digitalWrite(pinE, B1);
       digitalWrite(pinF, B0);
       digitalWrite(pinG, B0);
     break;
     
     case MWMillisOn < 6000:
       digitalWrite(pinA, B1);
       digitalWrite(pinB, B0);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B1);    //4
       digitalWrite(pinE, B1);
       digitalWrite(pinF, B0);
       digitalWrite(pinG, B0);
     break;
     
     case MWMillisOn < 7000:
       digitalWrite(pinA, B0);
       digitalWrite(pinB, B0);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B0);    //3
       digitalWrite(pinE, B1);
       digitalWrite(pinF, B1);
       digitalWrite(pinG, B0);
     break;
     
     case MWMillisOn < 8000:
       digitalWrite(pinA, B0);
       digitalWrite(pinB, B0);
       digitalWrite(pinC, B1);
       digitalWrite(pinD, B0);    //2
       digitalWrite(pinE, B0);
       digitalWrite(pinF, B1);
       digitalWrite(pinG, B0);
     break;
     
     case MWMillisOn < 9000:
       digitalWrite(pinA, B1);
       digitalWrite(pinB, B0);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B1);    //1
       digitalWrite(pinE, B1);
       digitalWrite(pinF, B1);
       digitalWrite(pinG, B1);
     break;
     
     case MWMillisOn < 10000:
       digitalWrite(pinA, B0);
       digitalWrite(pinB, B0);
       digitalWrite(pinC, B0);
       digitalWrite(pinD, B0);    //0
       digitalWrite(pinE, B0);
       digitalWrite(pinF, B0);
       digitalWrite(pinG, B1);
     break;

    case MWMillisOn >= 10000:
      MWOn = false; // switching off MW oven
      // Switch off MW light
      // Switch off MW motor
       digitalWrite(pinA, B1);
       digitalWrite(pinB, B1);
       digitalWrite(pinC, B1);
       digitalWrite(pinD, B1);    //0
       digitalWrite(pinE, B1);
       digitalWrite(pinF, B1);
       digitalWrite(pinG, B1);     
    break;
 
}
  }
  else {}
}


while compiling it gives some strange errors from which I understand, that I screwed up with syntax completely((( Please help!

Go Up