Well, te problem is actually the same provided that you write correctly the first program.
How did you solve the button problem? My suggestion is to use a simple state machine:
const byte ledPin = 13;
const byte buttonPin = 2;
const int onTimeMs = 1000; // The time the led should be on
// In this state the board waits
// for the user input
#define STATE_WAITING 0
// In this state the button was
// pressed (so the led is on)
#define STATE_PRESSED 1
// In this state the board is waiting
// for the button to be released
#define STATE_WAITREL 2
byte currState;
unsigned long pressTime;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
currState = STATE_WAITING;
}
void loop() {
switch (currState)
{
case STATE_WAITING:
if (digitalRead(buttonPin) == LOW)
{
digitalWrite(ledPin, HIGH);
pressTime = millis();
currState = STATE_PRESSED;
}
break;
case STATE_PRESSED:
if ((millis() - pressTime) > onTimeMs)
{
digitalWrite(ledPin, LOW);
currState = STATE_WAITREL;
}
break;
case STATE_WAITREL:
if (digitalRead(buttonPin) == HIGH)
currState = STATE_WAITING;
break;
}
}
In this case you can be in three states: waiting for the button press, waiting for the led to turn off (after one second) and waiting for the user to release the button.
So... The states remain the same even for the serial input, you just have to trigger the transitions in another way. The only problem is that the serial input is not continuous, so you have to determine what you mean by "stop sending". In my opinion, you can just set a timeout. The simplest way to achieve this is with this code, IMHO:
const byte ledPin = 13;
const char cmdChar = 'x';
const int onTimeMs = 1000; // The time the led should be on
const int timeoutCmdChar = 50; // The time the char should be off
// In this state the board waits
// for the user input
#define STATE_WAITING 0
// In this state the character was
// received (so the led is on)
#define STATE_RECEIVED 1
// In this state the board is waiting
// for the char to be absent
#define STATE_WAITABS 2
byte currState;
unsigned long recvTime;
unsigned long lastTimeCmdChar;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
currState = STATE_WAITING;
}
void loop() {
bool cmdCharReceived = false;
while (Serial.available())
{
if (Serial.read() == cmdChar)
{ // Received the character
cmdCharReceived = true;
lastTimeCmdChar = millis();
}
}
switch (currState)
{
case STATE_WAITING:
if (cmdCharReceived)
{
digitalWrite(ledPin, HIGH);
recvTime = millis();
currState = STATE_RECEIVED;
}
break;
case STATE_RECEIVED:
if ((millis() - recvTime) > onTimeMs)
{
digitalWrite(ledPin, LOW);
currState = STATE_WAITABS;
}
break;
case STATE_WAITABS:
if ((millis() - lastTimeCmdChar) > timeoutCmdChar)
currState = STATE_WAITING;
break;
}
}