我使用Neopixels(64个LED),并且我有一个名为level_up的函数,每次都会获得不同的led_num。通常,它是一个水平栏; level [1]将按从0到28的顺序点亮所有LED,level [2]将按29到48的顺序点亮所有LED,依此类推。
我附加的函数工作正常,但是我需要将延迟更改为millis(),但不确定如何。有什么想法吗?

uint8_t level[] = {0, 28, 48, 60, 64};  //levels 0 to 4


void level_up(uint8_t wait, uint8_t led_num) {
    uint8_t start_point;
    if (led_num == level[1]) start_point = 0;   //up from level 0 to 1
    if (led_num == level[2]) start_point = 28;  //up from level 1 to 2
    if (led_num == level[3]) start_point = 48;  //up from level 2 to 3
    if (led_num == level[4]) start_point = 60;  //...

    for (uint8_t i = start_point; i < led_num; i++) {
        strip.setPixelColor(i, strip.Color(0, 0, 255));
        strip.show();
        delay(wait);  //TODO: change it to timer
    }
}

void loop() {
    if (plus_btn.pressed()) {
        score++;
        if (score >= 4) {
            score = 4;
        }
    }
    if (minus_btn.pressed()) {
        score--;
        if (score <= 0) {
            score = 0;
        }
    }

switch (score) {
    case 0:
        if (last_score == 1) level_down(50, level[0]);
        last_score = 0;
        break;
    case 1:
        // if last_score was 0 make the blue effect because level is up
        if (last_score == 0) level_up(50, level[1]);
        // if last_score was 2 make the red effect because level is down
        if (last_score == 2) level_down(50, level[1]);
        last_score = 1;
        break;
    case 2:
        if (last_score == 1) level_up(50, level[2]);
        if (last_score == 3) level_down(50, level[2]);
        last_score = 2;
        break;
    case 3:
        if (last_score == 2) level_up(50, level[3]);
        if (last_score == 4) level_down(50, level[3]);
        last_score = 3;
        break;
    case 4:
        winning_timer.start();
        winning();
        digitalWrite(WINNING_SENSOR_PIN, HIGH);
        break;
}

Serial.println(score);


}

最佳答案

使用millis()不会像delay()那样阻塞for循环。
因此,我认为您将不得不调整正在调用您的方法的代码,因为目前看来您的代码依赖于在for循环中被阻塞。
但通常您会像下面的代码示例中那样使用millis()。您存储开始时间戳记,然后在等待时间结束后执行一些操作。

uint8_t level[] = {0, 28, 48, 60, 64};  //levels 0 to 4

uint8_t counter;
uint8_t end_point;
bool show_level;

void level_up(uint8_t wait, uint8_t led_num) {
    if (led_num == level[1]) counter = 0;   //up from level 0 to 1
    if (led_num == level[2]) counter = 28;  //up from level 1 to 2
    if (led_num == level[3]) counter = 48;  //up from level 2 to 3
    if (led_num == level[4]) counter = 60;  //...
    show_level =true;
    end_point = led_num;
}

bool set_pixel_color(uint8_t wait)
{
    if(timestamp - millis() == wait)
    {
        strip.setPixelColor(counter, strip.Color(0, 0, 255));
        strip.show();
        timestamp = millis();
        return true; // incremented
    }
    return false;
}

void show_level_led_strip()
{
    if(show_level)
    {
        if(counter > end_point) // escape when the counter gets bigger then the current led_num
        {
            show_level = false;
        }
        else
        {
            if(set_pixel_color(50))
            {
                counter++;
            }
        }
    }
}

void loop() {
    if (plus_btn.pressed()) {
        score++;
        if (score >= 4) {
            score = 4;
        }
    }
    if (minus_btn.pressed()) {
        score--;
        if (score <= 0) {
            score = 0;
        }
    }

    switch (score) {
        case 0:
            if (last_score == 1) level_down(level[0]);
            last_score = 0;
            break;
        case 1:
            // if last_score was 0 make the blue effect because level is up
            if (last_score == 0) level_up(level[1]);
            // if last_score was 2 make the red effect because level is down
            if (last_score == 2) level_down(level[1]);
            last_score = 1;
            break;
        case 2:
            if (last_score == 1) level_up(level[2]);
            if (last_score == 3) level_down(level[2]);
            last_score = 2;
            break;
        case 3:
            if (last_score == 2) level_up(level[3]);
            if (last_score == 4) level_down(level[3]);
            last_score = 3;
            break;
        case 4:
            winning_timer.start();
            winning();
            digitalWrite(WINNING_SENSOR_PIN, HIGH);
            break;
    }

    show_level_led_strip();
}

Serial.println(score);

关于c++ - 如何在此函数中使用millis()代替for循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58688181/

10-11 19:09