Problema delay nel combinare due sketch

Salve a tutti, ho un problema a collegare due sketch perchè i cicli si incrociano.
Spiego meglio, ho uno sketch per far illumminare una stripled tipo respiro:

#include <Adafruit_NeoPixel.h>

#define PIN 8
Adafruit_NeoPixel strip = Adafruit_NeoPixel(150, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.setBrightness(85);  // Lower brightness and save eyeballs!
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
int TOTAL_LEDS = 150;
float MaximumBrightness = 255;
float SpeedFactor = 0.03; // I don't actually know what would look good
float StepDelay = 10; // ms for a step delay on the lights

for (int i = 0; i < 65535; i++) {
float intensity = MaximumBrightness /2.0 * (1.0 + sin(SpeedFactor * i));
strip.setBrightness(intensity);
for (int ledNumber=0; ledNumber<TOTAL_LEDS; ledNumber++) {
strip.setPixelColor(ledNumber, 255,0, 0); //strip.setPixelColor(ledNumber, 0, 0, 255);
}

strip.show();
//Wait a bit before continuing to breathe
delay(StepDelay);
}
}

Poi un altro sketch per far girar in modo casuale 3 servo:

#include <Servo.h>

static const int servosPins[5] = {4, 16, 17};

Servo servos[5];

void setServos(int degrees) {
    for(int i = 0; i < 5; ++i) {
        servos[i].write((degrees + (35 * i)) % 180);
    }
}

void setup() {
    Serial.begin(115200);

    for(int i = 0; i < 5; ++i) {
        if(!servos[i].attach(servosPins[i])) {
            Serial.print("Servo ");
            Serial.print(i);
            Serial.println("attach error");
        }
    }
}

void loop() {
    for(int posDegrees = 0; posDegrees <= 180; posDegrees++) {
        setServos(posDegrees);
        Serial.println(posDegrees);
        delay(20);
    }

    for(int posDegrees = 180; posDegrees >= 0; posDegrees--) {
        setServos(posDegrees);
        Serial.println(posDegrees);
        delay(20);
    }
}

Unendo il codice prima si muovono i servo poi si interrompono e la striscia inizia il suo ciclo! Dove sta l'errore?

#include <Adafruit_NeoPixel.h>
#include <Servo.h>

static const int servosPins[3] = {11, 12, 13};
#define PIN 8
Servo servos[3];

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(150, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.setBrightness(85);  // Lower brightness and save eyeballs!
  strip.show(); // Initialize all pixels to 'off'
  
  Serial.begin(115200);
    for(int i = 0; i < 5; ++i) {
        if(!servos[i].attach(servosPins[i])) {
            Serial.print("Servo ");
            Serial.print(i);
            Serial.println("attach error");
        }
    }
    
}

void setServos(int degrees) {
    for(int i = 0; i < 5; ++i) {
        servos[i].write((degrees + (35 * i)) % 180);
    }
}

void loop() {
//Written by: Jason Yandell
    for(int posDegrees = 0; posDegrees <= 180; posDegrees++) {
        setServos(posDegrees);
        Serial.println(posDegrees);
        delay(20);
    }

    for(int posDegrees = 180; posDegrees >= 0; posDegrees--) {
        setServos(posDegrees);
        Serial.println(posDegrees);
        delay(20);
    }
    
int TOTAL_LEDS = 150;
float MaximumBrightness = 255;
float SpeedFactor = 0.03; // I don't actually know what would look good
float StepDelay = 10; // ms for a step delay on the lights

// Make the lights breathe
for (int i = 0; i < 65535; i++) {
// Intensity will go from 10 - MaximumBrightness in a "breathing" manner
float intensity = MaximumBrightness /2.0 * (1.0 + sin(SpeedFactor * i));
strip.setBrightness(intensity);
// Now set every LED to that color
for (int ledNumber=0; ledNumber<TOTAL_LEDS; ledNumber++) {
strip.setPixelColor(ledNumber, 255,0, 0); //strip.setPixelColor(ledNumber, 0, 0, 255);
}

strip.show();
//Wait a bit before continuing to breathe
delay(StepDelay);
}
}

Ovviamente nel fatto che se Arduino deve fare più cose "contemporaneamente" (in realtà non è mai contemporaneo ma "molto velocemente") non devi mai usare il delay perché questo interrompe l'elaborazione fino all'intervallo di tempo specificato, e non fa altro.
Devi imparare ad utilizzare la funzione millis(), se cerchi in questo forum o con google trovi valanghe di esempi e descrizioni, magari inizia da questo ad esempio.

... aggiung la mia solita "frasetta" che metto da anni su questo forum :grin:

... devi studiarti come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... vedrai che poi ti sarà tutto più chiaro :wink:

Studierò, prometto, ma intanto ho risolto così:

#include <Adafruit_NeoPixel.h>
#include <Servo.h>

static const int servosPins[5] = {11, 12, 13};
#define PIN 8
Servo servos[5];
Adafruit_NeoPixel strip = Adafruit_NeoPixel(150, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.setBrightness(85);  // Lower brightness and save eyeballs!
  strip.show(); // Initialize all pixels to 'off'
  Serial.begin(115200);
    for(int i = 0; i < 5; ++i) {
        if(!servos[i].attach(servosPins[i])) {
            Serial.print("Servo ");
            Serial.print(i);
            Serial.println("attach error");
        }
    }
}

void setServos(int degrees) {
    for(int i = 0; i < 5; ++i) {
        servos[i].write((degrees + (35 * i)) % 180);
    }
}

void lampeggia(){
int TOTAL_LEDS = 150;
float MaximumBrightness = 255;
float SpeedFactor = 0.03;
float StepDelay = 10;

  for (int i = 0; i < 65535; i++) {
  float intensity = MaximumBrightness /2.0 * (1.0 + sin(SpeedFactor * i));
  **setServos(i);**
  strip.setBrightness(intensity);
    for (int ledNumber=0; ledNumber<TOTAL_LEDS; ledNumber++) {
    strip.setPixelColor(ledNumber, 255,0, 0); //strip.setPixelColor(ledNumber, 0, 0, 255);
    }
  strip.show();
  delay(StepDelay);
  }
}

void loop() {
   for(int posDegrees = 0; posDegrees <= 180; posDegrees++) {
        setServos(posDegrees);
        Serial.println(posDegrees);
        delay(20);
    }
     for(int posDegrees = 180; posDegrees >= 0; posDegrees--) {
        setServos(posDegrees);
        Serial.println(posDegrees);
        delay(20); lampeggia();
    } 
}

In pratica ho messo il lampeggio in una funzione chiamata lampeggia ed al suo interno viene chiamata la funzione dei servo!

Non capirò mai perché negli esempi mettono sempre la movimentazione dei servo in dei cicli bloccanti...

Una volta che hai impostato la posizione di un servo con l'istruzione specifica, l'elettronica e la meccanica del servo farà tutto quello che serve, non c'è alcun bisogno di usare degli inutili cicli for o delay().

Suppongo per fare gli sweep della posizione, che scriverli in modo non bloccante sarebbe una complicazione inutile nel contesto dell'esempio.

Mi sa che non hai riportato il programma giusto!
Riguardo millis(), leggi anche qui:

Se LED e servo devono fare passi contemporanei, però, puoi anche usare la stessa temporizzazione per entrambi e, a quel punto, il delay() funziona ugualmente:

loop()
{
- Fai un passo alle luci
- Fai un passo al servo
- Aspetta un momento
}

Naturalmente non puoi usare dei for(): devi incrementare le variabili a ogni giro di loop e azzerarle quando raggiungono il valore massimo.
Per fare avanti e indietro, puoi incrementare da 0 a 360 e mettere:

if(degrees>180) valore=360-degrees;
else valore=degrees;

Lo sketch come da me modificato funziona. La luce di sfondo deve lampeggiare effetto "breath", mentre i servo devono effettuare movimenti random tutti diversi!

Ah! Non avevo visto lampeggia(); in fondo.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.