[SOLVED] Simple blink function does not work

Hi guys,

I have a reverse geocaching box which I would like to gently modify. The function is pretty easy. You push a button, it starts, seeking gps signal and when you are in a specific radius it opens. If you are too far away, it shows a message which the distance in m/km on a 16x2 lcd.

Long story short, I would like the led from the button flashing while it is seeking for gps. Somehow it didn't work like I would. I made it very simple and just added in the loop the function read pin, if its "high" turn it of, wait a sec and turn it on. So far this is working but the gps (I am using Tiny GPS Library) is doing nothing.

when I place that part of code under the "if (ss.available() && tinyGps.encode(ss.read())){" then it seems to work. But it starts flashing only when it found the gps signal.

Hope this is plausible explained and someone can help me fixing this tiny issue.

void loop()
{
    if (digitalRead(10) == HIGH)
    {
    digitalWrite(LED_PIN, LOW);
    delay(1000);
    digitalWrite(LED_PIN, HIGH);
    delay(1000);
  
  if (ss.available() && tinyGps.encode(ss.read()))
  {

    float lat, lon;
    unsigned long fixAge;

    tinyGps.f_get_position(&lat, &lon);

    digitalWrite(LED_PIN, HIGH);
    
    if (fixAge != TinyGPS::GPS_INVALID_AGE)
    {
     // Chirp(true);
      
      float distance_meters = TinyGPS::distance_between(lat, lon, DEST_LATITUDE, DEST_LONGITUDE);

Please post ALL the code, and explain your modifications. For example, what is the input on pin 10?

jremington:
Please post ALL the code, and explain your modifications. For example, what is the input on pin 10?

Pin 10 was not correct, this was related with a previous test where I set pin 10 to output. It has to be the LED_PIN.
Here is the complete code:

#include <PWMServo.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>

// -------------------------------------------------------------------
static const int   SERVO_CLOSED_ANGLE = 90;    // degrees (0-180)
static const int   SERVO_OPEN_ANGLE = 165;     // degrees (0-180)
static const float DEST_LATITUDE = 47.000000;  // degrees (-90 to 90)
static const float DEST_LONGITUDE = 9.000000; // degrees (-180 to 180)
static const int   RADIUS = 500;              // meters
static const int   LCD_CONTRAST = 20;          // (0-255)
// -------------------------------------------------------------------

/* Fixed values should not need changing */
static const int DEF_ATTEMPT_MAX = 50;
static const int EEPROM_OFFSET = 100;

/* Pin assignments */
static const int GPS_RX_PIN = 4, GPS_TX_PIN = 3; // GPS
static const int LCD_ENABLE_PIN = 7, LCD_RS_PIN = 5, LCD_RW_PIN = 8; // LCD
static const int LCD_DB4_PIN = 14, LCD_DB5_PIN = 15, LCD_DB6_PIN = 16, LCD_DB7_PIN = 17;
static const int LCD_CONTRAST_PIN = 6; 
static const int POLOLU_SWITCH_PIN = 12; // Pololu switch control
static const int SERVO_CONTROL_PIN = 9; // Servo control
static const int LED_PIN = 2; // The button LED
static const int PIEZO_PIN = 11; // Piezo buzzer outlet

/* The basic objects needed */
static SoftwareSerial ss(GPS_RX_PIN, GPS_TX_PIN);
static LiquidCrystal lcd(LCD_RS_PIN, LCD_RW_PIN, LCD_ENABLE_PIN, LCD_DB4_PIN, LCD_DB5_PIN, LCD_DB6_PIN, LCD_DB7_PIN);
static TinyGPS tinyGps; 
static int attemptCounter;
static PWMServo servo;

/* The Arduino setup() function */
void setup()
{
  /* Uncomment this code if you want to reset the attempt counter. */
  /*
    EEPROM.write(EEPROM_OFFSET, 0);
    exit(0);
  */

  /* First, make sure Pololu switch pin is OUTPUT and LOW */
  pinMode(POLOLU_SWITCH_PIN, OUTPUT);
  digitalWrite(POLOLU_SWITCH_PIN, LOW);

  /* attach servo motor */
  servo.attach(SERVO_CONTROL_PIN);

  /* establish a debug session with a host computer */
  Serial.begin(115200);

  /* establish communications with the GPS module */
  ss.begin(4800);

  /* set the LCD contrast value */
  pinMode(LCD_CONTRAST_PIN, OUTPUT);
  analogWrite(LCD_CONTRAST_PIN, LCD_CONTRAST);

  /* establish communication with 8x2 LCD */
  lcd.begin(8, 2); // this for an 8x2 LCD -- adjust as needed 
  
  /* turn on the LED in the button */
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  /* make sure motorized latch is closed */
  servo.write(SERVO_CLOSED_ANGLE); 
  
  /* read the attempt counter from the EEPROM */
  attemptCounter = EEPROM.read(EEPROM_OFFSET);
  if (attemptCounter == 0xFF) // brand new EEPROM?
    attemptCounter = 0;

  /* increment it with each run */
  ++attemptCounter;

  /* Greeting */
  Msg(lcd, "Welcome", "to your", 2000);
  Msg(lcd, "puzzle", "box!", 2000);

  /* Game over? */
  if (attemptCounter >= DEF_ATTEMPT_MAX)
  {
    Msg(lcd, "Sorry!", "No more", 2000);
    Msg(lcd, "attempts", "allowed!", 2000);
    Msg(lcd, "Please", "Contact", 2000);
    Msg(lcd, "the", "owner!", 2000);
    PowerOff();
  }

  /* Print out the attempt counter */
  Msg(lcd, "This is", "attempt", 2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(attemptCounter);
  lcd.print(" of "); 
  lcd.print(DEF_ATTEMPT_MAX);
  delay(2000);

  /* Save the new attempt counter */
  EEPROM.write(EEPROM_OFFSET, attemptCounter);

  Msg(lcd, "Seeking", "Signal...", 0);
}

/* The Arduino loop() function */
void loop()
{

/* This is my modification */
    if (digitalRead(LED_PIN) == HIGH)
    {
    digitalWrite(LED_PIN, LOW);
    delay(1000);
    digitalWrite(LED_PIN, HIGH);
    delay(1000);

/* Here my modification ends plus a } after PowerOFF(); */

  /* Has a valid NMEA sentence been parsed? */
  if (ss.available() && tinyGps.encode(ss.read()))
  {
    float lat, lon;
    unsigned long fixAge;

    /* Have we established our location? */
    tinyGps.f_get_position(&lat, &lon, &fixAge);
    if (fixAge != TinyGPS::GPS_INVALID_AGE)
    {
      /* We got a fix! */
      Chirp(true);
      
      /* Calculate the distance to the destination */
      float distance_meters = TinyGPS::distance_between(lat, lon, DEST_LATITUDE, DEST_LONGITUDE);

      /* Are we close?? */
      if (distance_meters <= RADIUS)
      {
        Msg(lcd, "Access", "granted!", 2000);
        servo.write(SERVO_OPEN_ANGLE);
      }

      /* Nope.  Print the distance. */
      else
      {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Distance");
        lcd.setCursor(0, 1);
        if (distance_meters < 1000)
        {
          lcd.print((int)distance_meters);
          lcd.print(" m.");
        }

        else
        {
          lcd.print((int)(distance_meters / 1000));
          lcd.print(" km.");
        }
        delay(4000);
        Msg(lcd, "Access", "Denied!", 2000);
      }
}
      PowerOff();
    }
  }

  /* Turn off after 5 minutes */
  if (millis() >= 300000)
    PowerOff();
}

/* Called to shut off the system using the Pololu switch */
void PowerOff()
{
  Chirp(false);
  Msg(lcd, "Powering", "Off!", 2000);
  lcd.clear(); 
  
  /* Bring Pololu switch control pin HIGH to turn off */
  digitalWrite(POLOLU_SWITCH_PIN, HIGH);

  /* This is the back door.  If we get here, then the battery power */
  /* is being bypassed by the USB port.  We'll wait a couple of */
  /* minutes and then grant access. */
  delay(120000);
  servo.write(SERVO_OPEN_ANGLE); // and open the box 

  /* Reset the attempt counter */
  EEPROM.write(EEPROM_OFFSET, 0); 
  
  /* Leave the latch open for 10 seconds */
  delay(10000); 

  /* And then seal it back up */
  servo.write(SERVO_CLOSED_ANGLE); 

  /* Exit the program for real */
  exit(1);
} 

/* A helper function to display messages of a specified duration */
void Msg(LiquidCrystal &lcd, const char *top, const char *bottom, unsigned long del)
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(top);
  lcd.setCursor(0, 1);
  lcd.print(bottom);
  delay(del);
}

static void Chirp(bool up)
{
  static const int A = 1760;
  static const int E = 2637;
  static const int CS = 2218;
  static const int duration = 100;

  int tone1 = up ? A : E;
  int tone2 = up ? E : A;

  ss.end();
  tone(PIEZO_PIN, tone1, duration);
  delay(duration);
  noTone(PIEZO_PIN);
  tone(PIEZO_PIN, tone2, duration);
  delay(duration);
  noTone(PIEZO_PIN);
  ss.begin(4800);
}

My modification start at the beginning of the loop. I simply want the button led on pin 2 to blink while it is seeking the gps signal. In this configuration it is blinking but it seems that the program is not continuing and seeking the signal.
If I add that LED blinking code under " if (ss.available() && tinyGps.encode(ss.read())) { like mentioned in my previous post, it works normal but the led start blinking only when it got signal.

/* This is my modification */
    if (digitalRead(LED_PIN) == HIGH)
    {
    digitalWrite(LED_PIN, LOW);
    delay(1000);
    digitalWrite(LED_PIN, HIGH);
    delay(1000);

/* Here my modification ends plus a } after PowerOFF(); */

  /* Has a valid NMEA sentence been parsed? */
  if (ss.available() && tinyGps.encode(ss.read()))

The one second delays make it impossible for the program to get a complete GPS reading, because the program spends almost all of the time doing nothing. You cannot use delay() in a program like this.

Please study this Blink Without Delay tutorial to learn a much more useful programming style.[/code]

Thank you very much. That helped a lot. I didn’t think about that the delay could cause such an issue.

The rest I should figure out by myself:)

No worries, soon I will post the next issue I am having with a thermal printer xD

Just to let you know in advance, I want to print random chars via a push button. Like an insult printer. It works almost fine but some of the texts having the issue that at the beginning the first letter is unreadable.

So stay tuned^^

You wrote "I want to print random chars via a push button. Like an insult printer. It works almost fine but some of the texts having the issue that at the beginning the first letter is unreadable.". If this is true, then it seems to be working just fine. Perhaps you need to limit the character set you use for random.

Paul

Paul_KD7HB:
You wrote "I want to print random chars via a push button. Like an insult printer. It works almost fine but some of the texts having the issue that at the beginning the first letter is unreadable.". If this is true, then it seems to be working just fine. Perhaps you need to limit the character set you use for random.

Paul

I opened a new topic since this one is already solved.
If you are interested you can find the post here: New Post

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