Эффект пишущей машинки (неблокирующий)C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Эффект пишущей машинки (неблокирующий)

Сообщение Anonymous »

Я работаю над эффектом печатного текста на дисплее Nextion. Первоначально я использовал цикл for, и он работал хорошо, за исключением того факта, что он блокировал остальную часть цикла (у меня идет обратный отсчет, и он зависал в то время, когда подсказки печатались на следующем дисплее). При таком подходе с оператором If я получаю только один символ при каждом вызове подсказки. Спасибо!
void typewriterEffect(const char* message, NexText& textComponent, unsigned long delayTime)
{
static String currentText = "";
static int charIndex = 0;
static unsigned long previousMillis = 0;
static bool messageComplete = false;

unsigned long currentMillis = millis();

if (!messageComplete && (currentMillis - previousMillis >= delayTime)) {
previousMillis = currentMillis;

if (message[charIndex] != '\0') {
currentText += message[charIndex];
charIndex++;
if (charIndex % 30 == 0 && message[charIndex] == ' ') {
currentText += "\r\n";
}
textComponent.setText(currentText.c_str());
Serial.print("Current Text: ");
Serial.println(currentText);
} else {
messageComplete = true;
Serial.println("Message complete");
}
}

// Reset for the next message
if (messageComplete) {
currentText = "";
charIndex = 0;
messageComplete = false;
}
}


Вот оставшаяся часть основного цикла:
void loop()
{
unsigned long currentMillis = millis();
interval = 1000; // Normal countdown speed

// Check if it's time to update the countdown
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
// Convert the countdown number to minutes and seconds
int minutes = countdownValue / 60;
int seconds = countdownValue % 60;
char buffer[10];
sprintf(buffer, "%02d:%02d", minutes, seconds);
// Set the text of the Nextion component to the countdown number
countdownText.setText(buffer);
// Decrement the countdown value
countdownValue--;
// Reset the countdown if it reaches 0
if (countdownValue < 0)
{
countdownValue = countdownStart;
// Trigger the solenoid
digitalWrite(SOLENOID, HIGH);
delay(5000); // Keep the solenoid on for 5 seconds
digitalWrite(SOLENOID, LOW);
}
}

switch (phase)
{
case MANUAL_PHASE:
if (!manualPromptDisplayed) {
typewriterEffect("See Manual", promptText, 100);
manualPromptDisplayed = true;
previousMillis = millis(); // Start the timer for the 3-second display
}
if (millis() - previousMillis >= 3000) {
previousMillis = millis();
Serial.println("Transitioning to BUTTON_PHASE1");
phase = BUTTON_PHASE1;
}
break;

case BUTTON_PHASE1:
if (!classificationPromptDisplayed) {
typewriterEffect("Prompttt", promptText, 100);
typewriterEffect("If Y is a high Z, press green button 1; if it is a low, press red button ", promptText, 100);
classificationPromptDisplayed = true;
}
int reading1 = digitalRead(BUTTON1);
int reading2 = digitalRead(BUTTON2);
if (reading1 != lastButtonState1) {
lastDebounceTime1 = millis();
}
if ((millis() - lastDebounceTime1) > debounceDelay) {
if (reading1 == LOW) {
// Perform action for button 1 press
if (correctAnswer1 == BUTTON1) {
typewriterEffect("Correct", promptText, 100);
phase = BUTTON_PHASE2; // Transition to the next phase
} else {
countdownValue -= 30; // Subtract 30 seconds from the countdown
typewriterEffect("Incorrect: Time deducted", promptText, 100);
}
}
}
lastButtonState1 = reading1;

if (reading2 != lastButtonState2) {
lastDebounceTime2 = millis();
}
if ((millis() - lastDebounceTime2) > debounceDelay) {
if (reading2 == LOW) {
// Perform action for button 2 press
if (correctAnswer2 == BUTTON2) {
typewriterEffect("Correct", promptText, 100);
phase = BUTTON_PHASE2; // Transition to the next phase
} else {
countdownValue -= 30; // Subtract 30 seconds from the countdown
typewriterEffect("Incorrect: Time deducted", promptText, 100);
}
}
}
lastButtonState2 = reading2;
break;

case BUTTON_PHASE2:
if (!buttonPhase2PromptDisplayed) {
typewriterEffect("Promptttttt", promptText, 100);
typewriterEffect("If Y is a primary Z, press green button 1; if it is a low, press red button ", promptText, 100);
buttonPhase2PromptDisplayed = true;
}
reading1 = digitalRead(BUTTON1);
reading2 = digitalRead(BUTTON2);
if (reading1 != lastButtonState1) {
lastDebounceTime1 = millis();
}
if ((millis() - lastDebounceTime1) > debounceDelay) {
if (reading1 == LOW) {
// Perform action for button 1 press
if (correctAnswer1 == BUTTON1) {
typewriterEffect("Correct", promptText, 100);
phase = WIRE_PHASE; // Transition to the next phase
} else {
countdownValue -= 30; // Subtract 30 seconds from the countdown
typewriterEffect("Incorrect: Time deducted", promptText, 100);
}
}
}
lastButtonState1 = reading1;

if (reading2 != lastButtonState2) {
lastDebounceTime2 = millis();
}
if ((millis() - lastDebounceTime2) > debounceDelay) {
if (reading2 == LOW) {
// Perform action for button 2 press
if (correctAnswer2 == BUTTON2) {
typewriterEffect("Correct", promptText, 100);
phase = WIRE_PHASE; // Transition to the next phase
} else {
countdownValue -= 30; // Subtract 30 seconds from the countdown
typewriterEffect("Incorrect: Time deducted", promptText, 100);
}
}
}
lastButtonState2 = reading2;
break;

case WIRE_PHASE:
typewriterEffect("Wire phase", promptText, 100);
// Add logic for wire phase here
break;
}
}


Подробнее здесь: https://stackoverflow.com/questions/792 ... n-blocking
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»