Scrolling question

i am trying to get my arduino LCD to scroll from the date on the first row of the lcd to say "Pet Feeder" in sort of an infinite scroll. (i.e. it looks as if it is continuously scrolling between the two. Id like it to say pet feeder for about 5 seconds before scrolling to the date for another 5 seconds. and continue this 24/7 i tried my hand at just trying to get it to scroll but so far all i did was make it blink and it was completely wrong... here is the code i made, and below that is the original code before i wanted it to scroll.

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <TimeAlarms.h>
#include <Time.h>

RTC_DS1307 RTC;
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
int motorPin = 2;
int lastHour = 23;
int lastMinute = 59;

bool feedPet = false;
unsigned long feedTime = 0;
unsigned long lastPrintTime = 0;

struct FeedTime {
  int hour, minute;
};

FeedTime amFeed = {10, 0};  // i.e. 10:00am
FeedTime pmFeed = {17, 30};  // i.e. 5:30pm

void setup ()
{
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  Wire.begin();
  RTC.begin();

  /*{
    lcd.println("RTC NOT Running!");
    RTC.adjust(DateTime((__DATE__), (__TIME__)));
  }*/
}

void loop ()
{
  DateTime now = RTC.now();
  FeedTime currentTime;
  currentTime.hour = now.hour();
  currentTime.minute = now.minute();
  if ((currentTime.minute != lastMinute) && (((currentTime.hour == amFeed.hour) && (currentTime.minute == amFeed.minute)) || ((currentTime.hour == pmFeed.hour) && (currentTime.minute == pmFeed.minute))))
  {
    feedTime = millis();
    feedPet = true;
    //lastHour = currentTime.hour; // <<<<<<<<<<<<<<< I removed this
  }
  lastMinute = currentTime.minute; //<<<<<<<<<<<<< I Forgot This
  if (feedPet)
  {
    turnFeeder();
  }
  if (millis() - lastPrintTime > 1000UL)
  {
    {
      lcd.setCursor(0, 0);

      {
        lcd.print("   Pet Feeder   ");
        delay(1000);
      }
      // turn off automatic scrolling
      lcd.noAutoscroll();
    }

    lcd.setCursor(0, 0);
    char nowDate[24] = "";
    sprintf(nowDate, "DATE: %02d/%02d/%d", now.month(), now.day(), now.year());
    lcd.print(nowDate);
    lcd.setCursor(0, 1);
    char nowTime[24] = "";
    sprintf(nowTime, "Time: %02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.print(nowTime);
    lastPrintTime = millis();
  }
}

void turnFeeder(void)
{
  static bool pinState = true;
  if (millis() - feedTime < 50500UL) // 50.5 second(s)
  {
    if (pinState)
    {
      digitalWrite(motorPin, HIGH);
      pinState = false;
    }
  }
  else
  {
    digitalWrite(motorPin, LOW);
    pinState = true;
    feedPet = false;
  }
}

original code

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <TimeAlarms.h>
#include <Time.h>

RTC_DS1307 RTC;
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
int motorPin = 2;
int lastHour = 24;
int lastMinute = 60;

bool feedPet = false;
unsigned long feedTime = 0;
unsigned long lastPrintTime = 0;

struct FeedTime{
  int hour, minute;
};

FeedTime amFeed = {9, 30};  // i.e. 9:30am
FeedTime pmFeed = {17, 30};  // i.e. 5:30pm

void setup ()
{
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  Wire.begin();
  RTC.begin();
  /*{
    lcd.println("RTC NOT Running!");
    RTC.adjust(DateTime((__DATE__), (__TIME__)));
  }*/
}

void loop ()
{
  DateTime now = RTC.now();
  FeedTime currentTime;
  currentTime.hour = now.hour();
  currentTime.minute = now.minute();
  if((currentTime.minute != lastMinute) && (((currentTime.hour == amFeed.hour) && (currentTime.minute == amFeed.minute)) || ((currentTime.hour == pmFeed.hour) && (currentTime.minute == pmFeed.minute))))
  {
    feedTime = millis();
    feedPet = true;
  }
  lastMinute = currentTime.minute;
  if (feedPet)
  {
    turnFeeder();
  }
  if (millis() - lastPrintTime > 1000UL)
  {
    lcd.setCursor(0, 0);
    char nowDate[24] = "";
    sprintf(nowDate, "DATE: %02d/%02d/%d", now.month(), now.day(), now.year());
    lcd.print(nowDate);
    // display the time
    lcd.setCursor(0, 1);
    char nowTime[24] = "";
    sprintf(nowTime, "Time: %02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.print(nowTime);
    lastPrintTime = millis();
  }
}

void turnFeeder(void)
{
  static bool pinState = true;
  if (millis() - feedTime < 50500UL) // 50.5 second(s)
  {
    if (pinState)
    {
      digitalWrite(motorPin, HIGH);
      pinState = false;
    }
  }
  else
  {
    digitalWrite(motorPin, LOW);
    pinState = true;
    feedPet = false;
  }
}

What do you mean by "scroll between values"? Toggling between two values is one thing. Scrolling a long value, like a marque, is another.

When you have determined what you REALLY mean, writing the code is generally trivial. When you can't state what you want to do, writing the code is a whole lot more difficult. "I'll recognize it when I see it" doesn't hold water here.

i said that i wanted it to scroll from PET FEEDER to the current date in a loop fashion (continually) BUT i want Pet Feeder and the date to stay on the lcd for a delay of 5 seconds each, so a pause when they get to the middle of the lcd.

i said that i wanted it to scroll from PET FEEDER to the current date in a loop fashion

Yes, you did. But I have no idea what that means. Perhaps you could pick a date, such as 12/3/2016 and the text PET FEEDER, and show what you want to see on the screen at any given time. Is it:
PET FEEDER 12/3/
ET FEEDER 12/3/2
T FEEDER 12/3/20
etc.?

Or do you have something else in mind? No mind readers here.

yes that is what i want

There are two ways to do it. then. The easy way, that uses more memory, or the slightly harder way that uses less memory.

The easy way, first.

  1. Format the date string, however you want it to appear.
  2. Copy "PET FEEDER " to an array (strcpy()).
  3. Append the date string to the array (strcat())
  4. Append " PET FEEDER " to the array
  5. Append the date string to the array (strcat())
  6. Print a portion of the array to the LCD, starting at index = 0, for n characters (however wide you LCD is)
  7. Increment index
  8. Repeat steps 7 and 8, until index gets to the width of the screen. When that happens, reset index to 0.

The harder way is similar, except you skip steps 4 and 5, and you print from some point in the array until you fill the screen OR until you get to the end of the array. If getting to the end of the array is the ending condition, print some more characters from the front of the array, to fill the screen.

If you need help with either approach, feel free to say which approach and show what you tried.

paulS i just ran into a big problem with my new more torquey motor, it wont start up because there is not enough power from the 5v that the arduino provides. i am switching to a motorsheild and need some help changing my code, i have started a new thread on this with the code, i think the scrolling will have to wait, any help will be greatly appreciated.

Well, if you want to scroll "ABCDEFG_" (8 characters) as a marquee, what do you want to appear after (say) three loops?

You want "DEFG_ABC"

So after 3 loops, you want to print two blocks to the lcd. First you print 5 characters at location 0, starting with position 3 in the string, then you print 3 characters at position 5, starting at the beginning of the string. Observing that 5 is 8-3 (lenght of string minus the position), we conclude that to print the marquee, and assuming that you have a function that only prints n haracters of a string (rather than printing all of it), you want something like

void marquee(int x, int x, char* s, int step) {
  lcd.printAt(x, y, s+step, strlen(s) - step);
  if(step != 0)
    lcd.printAt(x + strlen(s) - step, y, s, step);
}

when i implement the code you gave me i get the following error codes...

Arduino: 1.7.7 (Windows 7), Board: "Arduino Uno"

Lena_Feeder_v3.0.ino: In function 'void marquee(int, int, char*, int)':

Lena_Feeder_v3.0.ino:105:7: error: 'class LiquidCrystal' has no member named 'printAt'

Lena_Feeder_v3.0.ino:105:27: error: 'Lena' cannot be used as a function

Lena_Feeder_v3.0.ino:107:9: error: 'class LiquidCrystal' has no member named 'printAt'

Lena_Feeder_v3.0.ino:107:29: error: 'Lena' cannot be used as a function

heres the code i used and how i used it

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <TimeAlarms.h>
#include <Time.h>

RTC_DS1307 RTC;
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
//int motorPin = 2;
int lastHour = 24;
int lastMinute = 60;

bool feedPet = false;
unsigned long feedTime = 0;
unsigned long lastPrintTime = 0;

struct FeedTime {
  int hour, minute;
};

FeedTime amFeed = {9, 30};  // i.e. 9:30am
FeedTime pmFeed = {17, 30};  // i.e. 5:30pm

//sets up motor 1
//int pinI1 = 8;
int pinI2 = 12;
int speedpin1 = 10;

//sets speed of motor
int speed = 255;

void setup ()
{
  //pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  Wire.begin();
  RTC.begin();
  //pinMode (pinI1, OUTPUT);
  pinMode (pinI2, OUTPUT);
  pinMode (speedpin1, OUTPUT);

  /*{
    lcd.println("RTC NOT Running!");
    RTC.adjust(DateTime((__DATE__), (__TIME__)));
  }*/
}

void loop ()
{
  DateTime now = RTC.now();
  FeedTime currentTime;
  currentTime.hour = now.hour();
  currentTime.minute = now.minute();
  if ((currentTime.minute != lastMinute) && (((currentTime.hour == amFeed.hour) && (currentTime.minute == amFeed.minute)) || ((currentTime.hour == pmFeed.hour) && (currentTime.minute == pmFeed.minute))))
  {
    feedTime = millis();
    feedPet = true;
  }
  lastMinute = currentTime.minute;
  if (feedPet)
  {
    turnFeeder();
  }
  if (millis() - lastPrintTime > 1000UL)
  {
    lcd.setCursor(0, 0);
    char nowDate[24] = "";
    sprintf(nowDate, "DATE: %02d/%02d/%d", now.month(), now.day(), now.year());
    lcd.print(nowDate);
    // display the time
    lcd.setCursor(0, 1);
    char nowTime[24] = "";
    sprintf(nowTime, "Time: %02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.print(nowTime);
    lastPrintTime = millis();
  }

  analogWrite(speedpin1, speed);
}

void turnFeeder(void)
{
  static bool pinState = true;
  if (millis() - feedTime < 15000UL) //15.0 second(s)
  {
    if (pinState)
    {
      //digitalWrite(motorPin, HIGH);
      digitalWrite(pinI2, HIGH); //motorshield code
      pinState = false;
    }
  }
  else
  {
    //digitalWrite(motorPin, LOW);
    digitalWrite(pinI2, LOW); //motorshieild code
    pinState = true;
    feedPet = false;
  
}
void marquee(int Lena, int Feeder, char* s, int step)
{
  lcd.printAt(Lena (Feeder), s+step, strlen(s) - step);
  if(step != 0)
    lcd.printAt(Lena (Feeder) + strlen(s) - step, s, step);
}

no one knows how to get it to scroll properly? or why my code is wrong.

or why my code is wrong.

The compiler told you why it is wrong. You are trying to call methods that don't exist. Call only methods that actually exist.

i used the code he gave me and i got multiple errors for integers already being used. mainly for x