Author Topic: Programming question  (Read 11028 times)

XtremeIN

  • Newbie
  • *
  • Posts: 21
Programming question
« on: February 27, 2013, 11:58:45 pm »
Hello all,
 
I am working on a simple DigiSpark project. I am trying to get a simple LED blink sequence to work.  What I want is when pin 4 goes LOW start the sequence.  The sequence should be:
LED on for 1 sec, off for one sec, repeat 6 times
LED on for 3 sec
LED off for .5 sec, on for .5 sec, repeat 2 times
then repeat the 3 sec on blink twice untill the input goes HIGH.
My program goes through the sequence correct the first time then repeats the entire sequence over. I have tried several different way to get the last part to loop, but without avail.
 

int brakeinput = 4;
int brakeoutput = 1;
void setup()
{
  pinMode (brakeinput, INPUT);
  pinMode (brakeoutput, OUTPUT);
}
void loop()
{
  if (digitalRead (brakeinput) == LOW)
  {
    for (int brakingblink = 0; brakingblink < 5; brakingblink++)
    {
      digitalWrite (brakeoutput, HIGH);
      delay (1000);
      digitalWrite (brakeoutput, LOW);
      delay (1000);
    }
    digitalWrite (brakeoutput, HIGH);
    delay (3000);
    int stopblink = 0;
    while (stopblink < 3)
    {
      digitalWrite (brakeoutput, LOW);
      delay (500);
      digitalWrite (brakeoutput, HIGH);
      delay (500);
      stopblink++;
    }
  }
}

 
Thanks,
Micheal
 
 

ephphatha

  • Newbie
  • *
  • Posts: 6
Re: Programming question
« Reply #1 on: February 28, 2013, 02:13:27 am »
Correct me if I'm misunderstanding you but does this describe the flow you want?

Code: [Select]
1. Check the signal level of pin 4
  - If HIGH, go to 1.
  - If LOW:
2.     Blink LED for 1 second 6 times, then for 3 seconds once, then for 0.5 seconds twice.
3.     Check the signal level of pin 4
      - If HIGH, go to 1.
      - If LOW:
4.         Blink LED for 3 seconds twice.
5.         Go to 3.

If so, what you have is mostly complete. What you are missing is step 3 and beyond in the pseudocode above.

Code: [Select]
void loop()
{ // Check the level of pin 4
  if (digitalRead (brakeinput) == LOW)
  { // If LOW blink LED for 1 second 6 times
    for (int i = 1; i<= 6; ++i)
    {
      digitalWrite (brakeoutput, HIGH);
      delay (1000);
      digitalWrite (brakeoutput, LOW);
      delay (1000);
    }

    // then for 3 seconds once
    for (int i = 1; i <= 1; ++i)
    {
      digitalWrite (brakeoutput, HIGH);
      delay (3000);
      digitalWrite(brakeoutput, LOW);
      delay(500);
    }

    // then for 0.5 seconds twice
    for (int i = 1; i <= 2; ++i)
    {
      digitalWrite (brakeoutput, HIGH);
      delay (500);
      digitalWrite (brakeoutput, LOW);
      delay (500);
    }

    // Continuously check the level of pin 4
    while (digitalRead(brakeinput) == LOW)
    { // If low blink LED for 3 seconds twice
      for (int i = 1; i <= 2; ++i)
      {
        digitalWrite(brakeoutput, HIGH);
        delay(3000);
        digitalWrite(brakeoutput, LOW);
        delay(500);
      }
    }
  }
}

loop() is called repeatedly by the digispark firmware, so we don't need a while loop containing the whole thing since we're not storing any internal state. We do need a while loop at the end to keep checking the status of the input pin, since we only want to drop out of that sequence when the input goes high again.

The way I've written the for loops is personal preference. It makes it clear that you're using the loops as a counter and not an array index if you start at 1 and count up to and include your end value.

Mark

  • Full Member
  • ***
  • Posts: 196
Re: Programming question
« Reply #2 on: February 28, 2013, 03:26:39 am »
 
ephphatha's code rectifies the problem, but one question springs to mind.
Do you really want the brake light doing the 6.5 sec first sequence regardless of if it was touched briefly.?
 
To use the internal pullups you also need to write the pin HIGH (.. digitalWrite(brakeinput, HIGH).. )
You may have already found this, but for Pin 4 you need to add an external pullup resistor as the USB zener pulls down the internal pullup.
 
 
Mark
 
 

Bluebie

  • Sr. Member
  • ****
  • Posts: 486
Re: Programming question
« Reply #3 on: February 28, 2013, 03:49:38 am »
It might be a better idea to remove the boot up delay from the digispark and just power it from the regular brake light circuit! Then you can have the beginning sequence in your setup() and the loopy bit in the loop, and it'll turn off as soon as you release your brake.


To remove the startup delay, check out this thread: http://digistump.com/board/index.php/topic,320.msg1649.html#msg1649 - it explains how to do it on Mac and Windows, but you'll need a wire or button to connect D5 to ground while you plug the spark in to USB when uploading programs after that modification is done - when D5 isn't connected to ground the digispark will run your program without delay!

XtremeIN

  • Newbie
  • *
  • Posts: 21
Re: Programming question
« Reply #4 on: February 28, 2013, 09:28:00 pm »
WOW, great response guys.
 
ephphatha: kinda, the first part is correct, blink 6 times at one second interval. After the sixth blink the brakelight should stay on for three seconds then blink twice for 1/2 second stay on for three second then blink twice for 1/2 second........ I will look closer at your code and test it and get back with you.
 
Mark: no, I do not want the entire sequence to run if the brake is just tapped. That will be the next part of my project. I am new to microprocessors and figured one step at a time would be best. I just picked pin 4 out of thin air.  I am currently using pin 1 and the built in LED.
 
Bluebie: again, one thing at a time. I have thought about removing the boot delay but have not gotten that far yet.
 
Thank you very much for the insight and suggestions.  I am sure I will be back with more question. If for some reason I get it finished on my own I will at the very least give you a heads up and maybe a video.
 
Micheal
« Last Edit: February 28, 2013, 09:38:51 pm by XtremeIN »

XtremeIN

  • Newbie
  • *
  • Posts: 21
Re: Programming question
« Reply #5 on: February 28, 2013, 10:25:36 pm »
After a few trials I got the code to work the way I wanted.  I made a few changes to the timing and counts to get the effect closer to what I want.
 
Thank you very much.  Now onto the next part of the project.
 
Code: [Select]

 
int brakeinput = 5;
int brakeoutput = 1;
void setup()
{
  pinMode (brakeinput, INPUT);
  pinMode (brakeoutput, OUTPUT);
}
void loop()
{ // Check the level of pin 4
  if (digitalRead (brakeinput) == LOW)
  { // If LOW blink LED for .75 second 5 times
    for (int i = 1; i<= 5; ++i)
    {
      digitalWrite (brakeoutput, HIGH);
      delay (750);
      digitalWrite (brakeoutput, LOW);
      delay (750);
    }
   
    // Continuously check the level of pin 4
    while (digitalRead(brakeinput) == LOW)
    { //If LOW turn on LED for 3 seconds
      digitalWrite(brakeoutput, HIGH);
      delay(3000);
      // blink LED for .5 seconds twice
      for (int i = 1; i <= 3; ++i)
      {
        digitalWrite(brakeoutput, LOW);
        delay(500);
        digitalWrite(brakeoutput, HIGH);
        delay(500);
      }
    }
  }
}


Micheal

XtremeIN

  • Newbie
  • *
  • Posts: 21
Re: Programming question
« Reply #6 on: March 01, 2013, 12:14:08 am »
Like I said, I'm back.....
 
Trying to change the bootloader.  I am using Windows Vista, 32 bit. It will not allow me to drop the micronucleus or .hex file into the command promt window.  Any suggections?
 
Thanks,
Micheal

XtremeIN

  • Newbie
  • *
  • Posts: 21
Re: Programming question
« Reply #7 on: March 01, 2013, 01:22:05 am »
After some time searching online I learned that you can not drag and drop into the Command Prompt of Vista. Send to TOYS 2.7 is a nice way around it.
 
Micheal

Mark

  • Full Member
  • ***
  • Posts: 196
Re: Programming question
« Reply #8 on: March 01, 2013, 04:32:43 am »
Michael
Well done for venturing in and having a go.
I always maintain that you learn much more by trying, rather than someone supplying you a solution.

There are plenty of tutorials, ideas and solutions for a number of similar things in the Arduino forums.

Obviously some things are specific to the ATtiny uP in a Digispark, but your code is 'normal' arduino.
One thing I miss is the Serial.print to debug my software errors (and there's a few), so if you have an Arduino board you can develop it on that and then load it into a Digispark.

Bluebie's idea is a good solution, however you can achieve similar results without changing the bootloader.

Basically you remove the delay(x) and store the Millis() time.
You compare the two times (always subtract) and while waiting for the time to expire, you keep reading the brake switch, and if it stops, then the sequence stops.

It's something worth looking at how to do, as it may come in handy later and for really long delays (...nothing worse than something that isn't responding.)

Mark

XtremeIN

  • Newbie
  • *
  • Posts: 21
Re: Programming question
« Reply #9 on: March 01, 2013, 11:25:31 pm »
So it seems I have hit another wall. I successfully removed the bootloader from the DigiSpark.  I confirmed this by trying to download a sketch with out the jumper from P5 to GND, sketch would not load. Then I tried it with the jumper from P5 to GND, sketch loaded, I think. The DigiSpark is not working correctly. I was using P1’s built in LED for all previous testing. After removing the bootloader and re-downloading the sketch the LED does not blink.  I tried P3. When I check the voltage of P3 it is a constant 2.906v to GND.  I tried the example sketch for blinking and LED (changed the Pin from 13 to 1), same results.
Please help…..
 
Micheal
 
edit: running Aurdino IDE 1.03
« Last Edit: March 01, 2013, 11:28:20 pm by XtremeIN »

Bluebie

  • Sr. Member
  • ****
  • Posts: 486
Re: Programming question
« Reply #10 on: March 02, 2013, 04:43:15 am »

Due to a mistake in the digispark arduino software (which will hopefully be fixed in the next version) the software does not automatically run your program as soon as it is uploaded. When using the jumper version this means you need to unplug the digispark when your upload is finished, remove the jumper (or stop pushing button if you use a button instead) and plug it back in - your program should run immediately when plugged back in. Normally people don't notice this problem because in the normal bootloader, it times out after 5 seconds of inactivity and runs your program regardless. The jumper version never times out.


If that doesn't work and if you want to make your digispark normal again:

You can restore the regular type of bootloader with 5 second delay instead of jumper by going through the same upload process again, but this time upload micronucleus/upgrade/releases/micronucleus-1.05-upgrade.hex instead of the jumper one. once it's uploaded, unplug the digispark, plug it back in, wait twenty seconds, and then upload your sketch via digispark arduino app in the usual way.


It's totally normal for P3 to be at about 2.6-3.6v when you aren't using it in it's default 'input' state. This is caused by the hardware which adds a USB connector to the chip. If you set it to be an output you can drive it high or low as usual.