No interrupt are not the answer. Get better friends.
@UKHeliBob has given you the only good answer.
No interrupt are not the answer. Get better friends.
@UKHeliBob has given you the only good answer.
You didn't try very hard. I have been through your code... it's not pretty I have to say, but there is no reason you can't write to the 7-segment display before flashing the LED (EDIT - changed my mind on that - see post #26). The LED flashing is not a great design as it includes blocking delay() statements, but regardless it should still do what you want.
Move the following code to the bottom of loop().
int inChar = number;
if (isDigit(inChar))
data += (char)inChar;
if (inChar == '\n' || inChar == '\r')
{
x = data.toInt();
Serial.print("value");
Serial.println(x);
Serial.println(x);
for (i = 0; i < x; i++)
{
digitalWrite(ledPin, state);
digitalWrite(7, HIGH);
delay(100);
digitalWrite(7, LOW);
delay(100);
}
data = "";
}
You also need to move the closing bracket "}" for this if statement...
if (Serial.available() > 0)
to after the code you just moved... so everything within loop() is inside the if.
I have tried, when viewed from the serial monitor, like you said. but the 7 segment display doesn't appear
As previously suggested the answer is to use non blocking code to blink the LED
See the BlinkWithoutDelay example in the IDE. For for more details see Using millis() for timing. A beginners guide and Several things at the same time
@UKHeliBob is correct.
I didn't realise quite how the 7 segment display is working but because the 3 digits share the same pins for the segments, then you can only display 1 digit at a time. You need to display each digit repeatedly one after the other (in a loop) - if this happens fast enough then it appears all 3 are on at the same time. See the code below (I added some comments) from your code - this lights a single digit.
disp.writeDigit(dsegArr[0]); // Set the segments required.
digitalWrite(seg1, LOW); // Turn on digit 1
delayMicroseconds(100); // Very small delay
digitalWrite(seg3, HIGH); // Turn off digit 3
digitalWrite(seg2, HIGH); // Turn off digit 2
digitalWrite(seg1, HIGH); // Turn off digit 1
If you want to see more clearly what is actually happening change the delayMicroseconds above to delay(1000), and you will see the digit turn on, then off again.
So your problem is that you have 2 loops in your program... one for displaying the 7 segment display, and one for blinking the LED. In your original code they run one after the other. What you need is a single loop (loop()), and you need to use millis() to determine when to do things (like turn on/off the LED, turn on/off a particular digit).
As suggested, have a look at the BlinkWithoutDelay example.
im still confused, okay is it, first make a new function for flash led. then how to get flash based on input serial data?. is it ok if i set flash function on "for" statement..
yeah actually at first I made 2 different programs for my project. then I try to merge into 1. but I just couldn't make it work with millis(). So I need you guys help to make this code work with millis() function. or can you make an example millis flash by serial input... Thanks for your help in advance
No that won't work. Because the for loop sets up a separate loop... to use millis effectively you only want ONE loop. Everything happens inside that loop.
Did you look at the example?
There are a few things you need keep track of... so you'll need variables for these.
Ok... I don't normally do this... I got bored... here's the code.
#include "SevenSeg.h"
#define ledPin 13
SevenSeg disp (30,31,32,33,34,35,36);
const int numOfDigits = 3;
int digitPins[numOfDigits] = {40,41,42};
uint16_t number; // This is the number we want to display.
uint8_t numberArray[3]; // This is the number split into individual digits. 100s, 10s, 1s.
boolean displaying = false; // We are either checking for user input, or displaying the input received.
uint8_t digit = 0; // Keeps track of which 7-segment digit to display (0, 1, 2).
boolean onLED = false; // Keeps track of whether the LED is currently on or off.
uint16_t toggleCount = 0; // Keeps track of how many times we have toggled (turned on/off) the LED.
unsigned long currentMillis; // Current time.
unsigned long lastToggledLED = 0; // The last time we toggled the LED.
void setup()
{
Serial.begin(115200);
disp.setDigitPins (numOfDigits, digitPins);
disp.setCommonAnode();
disp.setDutyCycle(50);
pinMode(ledPin, OUTPUT);
pinMode(digitPins[0], OUTPUT);
pinMode(digitPins[1], OUTPUT);
pinMode(digitPins[2], OUTPUT);
Serial.println("Enter a number 0 - 999");
}
void loop()
{
currentMillis = millis(); // Capture the current time.
if (displaying) // Are we currently displaying the received number?
{
displayDigit(numberArray[digit], digit); // Display a single digit on the 7 segment display.
digit = (digit + 1) % 3; // Determine next digit (0, 1, 2) to display on next loop.
if (currentMillis - lastToggledLED > 200) // Has it been long enough since we toggled the LED?
{
lastToggledLED = currentMillis; // Capture the last time we toggled the LED.
if (onLED) // Is the LED currently on?
{
digitalWrite (ledPin, LOW); // Turn LED off.
onLED = false; // Keep track of the LED state.
toggleCount++; // Keep track of how many times we have turned the LED on/off.
Serial.print("LED toggled, count "); // Display details to the monitor.
Serial.println(toggleCount);
}
else // LED is currently off.
{
digitalWrite (ledPin, HIGH); // Turn LED on.
onLED = true; // Keep track of the LED state.
}
if (toggleCount >= number) // Have we flashed the LED enough times?
{
toggleCount = 0; // Reset counter for next number.
displaying = false; // Stop displaying.
number = 0; // Clear the number.
digit = 0; // Clear the number of digits.
digitalWrite(digitPins[0], HIGH); // Turn off all digits.
digitalWrite(digitPins[1], HIGH);
digitalWrite(digitPins[2], HIGH);
}
}
}
else // Not displaying so check for input from user.
{
checkForInput(); // Check for a new number received.
}
}
void checkForInput()
{
if (Serial.available() > 0) // Has something been received?
{
char c = Serial.read(); // Read a single character.
if (c >= '0' && c <= '9') // Did we receive a digit?
{
number = (number * 10) + (c - '0'); // Calculate the number.
digit++; // Keep track of how many digits we have received.
}
else if ((c == '\n' || c == '\r') && digit > 0) // Did we receive the end of the input and have a number?
{
numberArray[0] = (number % 1000 / 100) ; // Set the hundreds digit.
numberArray[1] = (number % 100) / 10; // Set the tens digit.
numberArray[2] = (number % 10) / 1; // Set the ones digit.
Serial.print("Input received "); // Display details to the monitor.
Serial.println(number);
Serial.print("Digits are ");
Serial.print(numberArray[0]);
Serial.print(" ");
Serial.print(numberArray[1]);
Serial.print(" ");
Serial.println(numberArray[2]);
displaying = true; // Will trigger the number to start being displayed.
digit = 0; // Display digit 0 first.
}
}
}
void displayDigit(uint8_t value, uint8_t position)
{
// Serial.print("7 Segment display, digit "); // Display details to the monitor.
// Serial.print(position);
// Serial.print(" value ");
// Serial.println(value);
digitalWrite(digitPins[0], HIGH); // Turn off all digits
digitalWrite(digitPins[1], HIGH);
digitalWrite(digitPins[2], HIGH);
disp.writeDigit(value); // Set the individual segment lines.
digitalWrite(digitPins[position], LOW); // Turn on the required digit.
}
Even simpler
if (currentMillis - lastToggledLED > 200) // Has it been long enough since we toggled the LED?
{
lastToggledLED = currentMillis; // Capture the last time we toggled the LED.
digitalWrite (ledPin, !digitalRead(ledPin)); //change LED state
Serial.print("LED toggled, count "); // Display details to the monitor.
Serial.println(++toggleCount);
}
Although toggleCount will now be incremented twice per cycle…
With a variable of that name I would expect it to be counting how many times the pin state was toggled, which is what it does
thanks all, sorry for waste your time,,, but im still try my self in here,
i've try millis()
void blinkLed(int x)
{
// The led is immediately turned on,
// and after the first interval the led is turned off.
// That will be the first blink.
ledState = HIGH;
digitalWrite(ledPin, ledState);
// Start the blinking
previousMillis = millis(); // update the stored millis time to this moment.
count1 = 0; // start from zero
maxBlink = x; // blink up to this number
enable = true; // enable the millis-timer in the "update" function.
}
void updateLed()
{
// A 'currentMillis' variable is not needed, but is often handy
unsigned long currentMillis = millis();
if( enable) // should we blink ?
{
if( currentMillis - previousMillis > interval) // millis-timer
{
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
ledState = ledState == HIGH ? LOW : HIGH;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
// When the led has just turned low, increase the number that is blinked
if( ledState == LOW)
{
count1++;
if( count1 >= maxBlink)
{
enable = false; // enough with this blinking, stop it.
}
}
}
}
}
void loop(){
if(Serial.available() > 0)
{
unsigned long currentMillis = millis();
int inChar = Serial.read();
if(isDigit(inChar))data += (char)inChar;
int x = data.toInt();
if( x > 0) // was it a valid number ?
{
blinkLed( x); // Start the blinking of the led.
}
// Clear serial input buffer.
// There could be a linefeed and/or a carriage return.
while( Serial.available() > 0)
{
Serial.read(); // read it and throw it away
}
// In the main level of the loop(), run the millis-timer.
// This will only work if there are no long delays or
// while-loops in the rest of the loop().
updateLed();
data="";
/*
---- ALUR PROCEDURE MENERIMA DATA SERIAL ----
1. Tampung Data Serial ke Var Number
2. Kurangi isi data number dengan 0x30 , hasilnya adalah index ke table segment
3. Pindahakan data ke array table tmpArr[]
4. Cek data serial apakah data terakhir 0x0A atau 0x0D
Y : Update data segmen , copy tmpArr[] -> dsegArr[]
Debug Diserial Monitor , memastikan data benar
Variable Counter iX di Nolkan
Catat nilai variable iY
N : Keluar Prosedure , Next Prosedure
*/
number = inChar;
tmpArr[iX++] = number-48;
if (number==13 || number==10)
{
for(iY=0; iY<iX; iY++){dsegArr[iY]=tmpArr[iY];}
if(iY==4)
the result is the LED and the segment display is On at the same time but, the LED is not flashing. hahahaha.
anyway thanks for your help guys...
Please post your complete revised sketch
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.