Particle Spark (Arduino) Как вспыхивать 2 светодиодных последовательностей одновременно?

Я не могу найти информацию, связанную с моей проблемой. Несколько вещей, которые я нашел, меня смутили (я совершенно новичок в этом).

Я пытаюсь одновременно выпустить 2 последовательности из 4 огней. Я могу получить 1 набор мигающих, но я не знаю, как запускать другие последовательности одновременно. Моя вероятно смехотворная попытка кода ниже:

int led1 = D0; 
int led2 = D1; 
int led3 = D2; 
int led4 = D3; 
int led5 = D4; 
int led6 = D5; 
int led7 = D6; 
int led8 = D7; 

void setup() {
  setupPart1();
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  setupPart2();
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
}

void loop() {
  loopPart1();
  digitalWrite(led1, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led1, LOW);
  digitalWrite(led2, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led2, LOW);
  digitalWrite(led3, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led3, LOW);
  digitalWrite(led4, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led4, LOW);
  loopPart2();
  digitalWrite(led5, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led5, LOW);
  digitalWrite(led6, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led6, LOW);
  digitalWrite(led7, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led7, LOW);
  digitalWrite(led8, HIGH);
  delay(500); // delayed for half a second
  digitalWrite(led8, LOW);
}
led
2 голоса | спросил Ben Millen 5 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 05 Sep 2017 01:10:16 +0300 2017, 01:10:16

2 ответа


1

Я рассматриваю этот точный вопрос на своей веб-странице: http://www.gammon.com.au /моргать

Пример кода, который мигает двумя светодиодами с разной скоростью:

 // Which pins are connected to which LED
const byte greenLED = 12;
const byte redLED = 13;

// Time periods of blinks in milliseconds (1000 to a second).
const unsigned long greenLEDinterval = 500;
const unsigned long redLEDinterval = 1000;

// Variable holding the timer value so far. One for each "Timer"
unsigned long greenLEDtimer;
unsigned long redLEDtimer;

void setup () 
  {
  pinMode (greenLED, OUTPUT);
  pinMode (redLED, OUTPUT);
  greenLEDtimer = millis ();
  redLEDtimer = millis ();
  }  // end of setup

void toggleGreenLED ()
  {
   if (digitalRead (greenLED) == LOW)
      digitalWrite (greenLED, HIGH);
   else
      digitalWrite (greenLED, LOW);

  // remember when we toggled it
  greenLEDtimer = millis ();  
  }  // end of toggleGreenLED

void toggleRedLED ()
  {
   if (digitalRead (redLED) == LOW)
      digitalWrite (redLED, HIGH);
   else
      digitalWrite (redLED, LOW);

  // remember when we toggled it
  redLEDtimer = millis ();  
  }  // end of toggleRedLED

void loop ()
  {

  // Handling the blink of one LED.
  if ( (millis () - greenLEDtimer) >= greenLEDinterval)
     toggleGreenLED ();

  // The other LED is controlled the same way. Repeat for more LEDs
  if ( (millis () - redLEDtimer) >= redLEDinterval) 
    toggleRedLED ();

/* Other code that needs to execute goes here.
   It will be called many thousand times per second because the above code
   does not wait for the LED blink interval to finish. */

}  // end of loop
ответил Nick Gammon 5 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 05 Sep 2017 10:15:41 +0300 2017, 10:15:41
1

Эта проблема (несколько параллельных операций) достаточно частая, чтобы заслужить более элегантное решение. Хотя такие проекты превосходны ( Задачи: планировщик с тайм-аутом для Arduino ), я не могу заставить его работать.

Я написал этот минимальный автономный пример того, как делать две вещи одновременно. Он будет мигать встроенным светодиодом и записывать «*» на последовательный монитор:

--- Task Scheduler ---
Runtime in SS:MMMM
10:9 **********
110:64 **********
210:89 ***

Это эскиз. Изучите это и приспособите его к своей собственной проблеме:

/*
 * Task Scheduler for Arduino/ESP2866 by Look Alterno - 2017/8/9.0
 * Show how to execute tasks at regular intervals without using delay() or interrupts.
 * For educational purposes only; not production ready. 
 *
 * This sketch have two example tasks running:
 * - Task 1 blinks the builtin led every second
 * - Task 2 write lines with run time and one "*" every ten seconds in the Serial Monitor. 
 * Tasks are run in sequence, so keep them short.
 * No interrupts are used; you have to call runTasks() in each loop() pass.
 */

// Definition: Every task must receive nothing and return nothing.
typedef void (*fcnptr)();
//  Here we must declare our task functions (required by C)
void fcnBlink();      // Task 1
void fcnSerial();     // Task 2
//  Add more tasks here.

//  The interval between fcnBlink execution. Adjustable between 25 to 250 ms.
//  LED still will blink every second at the same freq (250ms on, 750ms off).
#define BLINK_LEN 25

//  The task list
struct {
    uint8_t  runnable;  // The task is runnable (true/false).
    uint32_t start;     // Next start time for the task (ms).
    uint32_t interval;  // Execution interval in ms.
    fcnptr fcn;          // Function to execute.
} taskList[] = {
    {true, 0, BLINK_LEN,fcnBlink}, // Execute fcnBlink every 25 ms, blink LED every second
    {true, 0, 10000,    fcnSerial} // Execute fcnSerial every 10 seconds.
    // Here you can add other tasks.
};
// The number of task in our task list.
const uint8_t nTasks = sizeof(taskList) / sizeof(taskList[0]);

void setup() {
  // Just a standard setup. Nothing is required for task execution.
  Serial.begin(9600);
  while(!Serial) {};
  randomSeed(analogRead(A0));
  Serial.println("");
  Serial.println("--- Task Scheduler ---");
  Serial.println("Runtime in SS:MMMM");
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // Here you write your processing code (without using delay())
  // --- Start of your code.
  // Some random delays to simulate work
  // Just a bit less than half fcnBlink interval length.
  // You can change BLINK_LEN to test other scenarios.

  delay(random(1, BLINK_LEN / 2));  

  // --- End of your code
  runTasks();  // At the end of the loop(), but can be anywhere.
}

/*
 * Check the task list and execute them.
 * Sequence of execution guaranteed: tasks could be delayed,
 * but not omitted or executed of order.
 */
void runTasks() {
  uint32_t now = millis();
  for(uint8_t i=0; i < nTasks; i++) {
    if(taskList[i].runnable) {
      uint32_t diff = now - taskList[i].start; // ms since last execution.
      if(diff >= taskList[i].interval) {
        taskList[i].start = now; // Have to be the same for all task, to keep sync.
        taskList[i].fcn();
      }
    }
  }
}

/*
 * Blink the led.
 */
void fcnBlink() {
  // Called every 25 milliseconds. Turn on the led in the
  // 10 first passes and turn off in the next 30.
  static uint8_t count = 0;
  count++;
  if(count <= 250 / BLINK_LEN) {
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
    if(count == 1000 / BLINK_LEN) {
      count = 0;
    }
  }
}

/*
 * Print run time (s) and a row of ten "*"
 */
void fcnSerial() {
  static uint8_t count = 0;
  count++;
  // Print run time in seconds:miliseconds at the start of each line
  if (count == 1) {
    uint32_t now = millis();
    Serial.print(now/1000);
    Serial.print(":");
    Serial.print(now%1000);
    Serial.print(" ");
  }
  Serial.print("*");
  if(count == 10) {
    Serial.println();
    count = 0;
  }
}
ответил 5 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 05 Sep 2017 11:01:28 +0300 2017, 11:01:28

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132