Аттракцион "Волк яйцелов"

mmc450
Offline
Зарегистрирован: 26.06.2018

Всем привет. Хочу сделать аттракцион "Волк яйцелов". https://www.youtube.com/watch?v=H03D73WJxlw примерно как тут. Шарики будут подаваться с помошью актуаторов (https://auto.today/bok/3835-aktuator-centralnogo-zamka.html). Помогите написать скейтч что бы в нем были нексолько уровней сложности (1 уровень предположим 1 шарик в секунду, 2 уровень 2 шарика в секунду и т.д.) но что бы при кажном запуске были разные последовательности. (а за всю игру дожны быть использованы все шарики (предпологаю поставить концевики на определения остались ли шарики, если нет то не использовать этот актуатор и т.п.) или может как то программно считать колличество истраченных шариков (предпологается что в каждом лотке по 15 шариков в начале игры. Получится ли использовать функцию рандом? или придется протисывать последовательности в ручную? Подскажите как лучще сделать? и примерный алгоритм если возможно? Спасибо заранее.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

тебе надо писать в "ищу исполнителя" а если хочешь бесплатно, то пиши что делаешь, и что у тебя не получается, а мы будем помогать исправлять, в любом случае у тебя должно быть хоть что то уже написанно

sadman41
Offline
Зарегистрирован: 19.10.2016

А зачем актуаторы? Тут надо что-то резкое, чтобы заслонку открывало, а шары пусть катятся под действием силы тяжести.

 

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

я думаю он и имел это ввиду

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

sadman41 пишет:

А зачем актуаторы? Тут надо что-то резкое, чтобы заслонку открывало, а шары пусть катятся под действием силы тяжести.

 

просто акутаторы будут открывать шторки

 

sadman41
Offline
Зарегистрирован: 19.10.2016

А они быстрые? В противном случае человек с хорошим слухом будет понимать, откуда полетит шар.

mmc450
Offline
Зарегистрирован: 26.06.2018

Бутут шторки, которыми и будут оправлять актуаторы, скоростьу них приличная.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

sadman41 пишет:

А они быстрые? В противном случае человек с хорошим слухом будет понимать, откуда полетит шар.

можно остальными просто щелкать вниз допустим, что бы тоже звук издавали какой нибудь))) 

mmc450
Offline
Зарегистрирован: 26.06.2018
#define LeUp 12
#define LeDo 10
#define RiUp 13
#define RiDo 11

void setup() {
  // put your setup code here, to run once:

}

void vibros(int xr){
  switch (xr) {
  case 1:
    digitalWrite(LeUp, HIGH);
    delay(150);
    digitalWrite(LeUp, LOW);
    delay (150);
    break;
  case 2:
    digitalWrite(LeDo, HIGH);
    delay(150);
    digitalWrite(LeDo, LOW);
    delay (150);
    break;
  case 3:
    digitalWrite(RiUp, HIGH);
    delay(150);
    digitalWrite(RiUp, LOW);
    delay (150);
    break;
  case 4:
    digitalWrite(RiDo, HIGH);
    delay(150);
    digitalWrite(RiDo, LOW);
    delay (150);
    break;
}
}


void loop() {
  // put your main code here, to run repeatedly:
int lot_ran = random(5);
vibros(lot_ran);
}

 

Вот никидал такой код, пока на светодиодах. Минус в том что рандом может выбрать одно и тоже число раз по 5. Соответственно в одном лотке очень быстро закончатся шарики и игра будет продолжаться с 3мя лотками. Писать алгоритмы вручную?? (хочется что бы хотя бы алгоритмов 5 разных было) Что скажете? 

mmc450
Offline
Зарегистрирован: 26.06.2018

И еще как можно организовать смену темпа? (менять уровни сложности, менять задержку по истечению какого то времени, или выбросу определенного количества шариков)

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

mmc450 пишет:

(хочется что бы хотя бы алгоритмов 5 разных было) Что скажете? 

сделай число побольше, не 5 а 200 допустим, и дели его потом на 40

получил там 36 - поделли на 40 получилось 0 - записал =1 и т.д. ну я не прям точною формулировку сделал, а просто подумай в этом направлении

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

mmc450 пишет:

И еще как можно организовать смену темпа? (менять уровни сложности, менять задержку по истечению какого то времени, или выбросу определенного количества шариков)

то что в скобках где delay(150) напиши delay(level) и потом где нибудь меняй значение level = 300,  level = 200, 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

mmc450 пишет:

Помогите написать скейтч что бы в нем были нексолько уровней сложности (1 уровень предположим 1 шарик в

Опять skaytch. Откуда это берётся блин? Ну допустим не владеете английским -есть же русское слово скетч. Зачем коверкать?

mmc450
Offline
Зарегистрирован: 26.06.2018

Учту замечание.

b707
Offline
Зарегистрирован: 26.05.2017

mmc450 пишет:
Вот никидал такой код, пока на светодиодах. Минус в том что рандом может выбрать одно и тоже число раз по 5.

Чтобы рандом выдавал случайное значение - нужно чтобы в скобках тоже стояло случайное число :) Сюда обычно вписывают результат чтения из аналогового порта, который ни к чему не подключен.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

mmc450 пишет:

Минус в том что рандом может выбрать одно и тоже число раз по 5. Соответственно в одном лотке очень быстро закончатся шарики и игра будет продолжаться с 3мя лотками. 

можешь еще записывать выпавшее числов рандоме в какую нибудь переменную, допустим рандом_1 = 4, и потом провеять его радом_2 = рандом_1, снова радом принимает какое то значение, записываешь его в рандом_1 и сверяешь, если радом_2 == рандом_1 то выполнить снова команду рандома, если отличается, то погнали выполнять программу

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

b707 пишет:

 

Чтобы рандом выдавал случайное значение - нужно чтобы в скобках тоже стояло случайное число :) Сюда обычно вписывают результат чтения из аналогового порта, который ни к чему не подключен.

а так незя делать( я оставил порты в воздухе, от моторчиков ардуино сходила с ума. как только подтянул их к земле, сразу ардуинка перестала зависать и перезагружаться

mmc450
Offline
Зарегистрирован: 26.06.2018

b707 пишет:

mmc450 пишет:
Вот никидал такой код, пока на светодиодах. Минус в том что рандом может выбрать одно и тоже число раз по 5.

Чтобы рандом выдавал случайное значение - нужно чтобы в скобках тоже стояло случайное число :) Сюда обычно вписывают результат чтения из аналогового порта, который ни к чему не подключен.

 

читал про эту возможность, только немного не понял. Какой диапозон чисел может попасть в рандом? И как мне после этого привезти в нужный вид числа. Предположим в рандом попадет число 700. а у меня всего 4 варианта.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

mmc450 пишет:

читал про эту возможность, только немного не понял. Какой диапозон чисел может попасть в рандом? И как мне после этого привезти в нужный вид числа. Предположим в рандом попадет число 700. а у меня всего 4 варианта.

самый простой вариант http://arduino.ru/Reference/Map - хотя это бред... 

надо формулу делаеть)))  и что бы в формуле контрольная цифра была  - значение с аналоговой ноги

b707
Offline
Зарегистрирован: 26.05.2017

mmc450 пишет:

 Предположим в рандом попадет число 700. а у меня всего 4 варианта.

Возьмите остаток от деления рандома на 4

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

mmc450 пишет:

Что скажете? 

Скажем, что зафиксирована попытка получить готовый код с нуля и на халяву, ни хрена не сделав самостоятельно. Попытчик отсылается лесом, прямо в платный раздел.

mmc450 пишет:

Вот накидал такой код

Накидывают навоз на грядку. Хотя это что-то похожее и есть. Если хочешь представить, что, типа, у тебя тут код есть, ты хоть пины сконфигурируй. А это не код – это отмаза на тему «я тут стараюсь, давайте делайте за меня в сё остальное». Ты бы ещё вот такое выложил

void setup(){}
void loop(){}

И сказал бы: «код, не пашет, помогите допилить».

mmc450 пишет:

Писать алгоритмы вручную??

Нет, сидеть ждать пока какой-нибудь добрый дядя за тебя напишет.

sadman41
Offline
Зарегистрирован: 19.10.2016

Ворота пишет:

void setup(){}

void loop(){}

Этот код как раз пашет на 100% ))

mmc450
Offline
Зарегистрирован: 26.06.2018

Ворота пишет:

mmc450 пишет:

Что скажете? 

Скажем, что зафиксирована попытка получить готовый код с нуля и на халяву, ни хрена не сделав самостоятельно. Попытчик отсылается лесом, прямо в платный раздел.

mmc450 пишет:

Вот накидал такой код

Накидывают навоз на грядку. Хотя это что-то похожее и есть. Если хочешь представить, что, типа, у тебя тут код есть, ты хоть пины сконфигурируй. А это не код – это отмаза на тему «я тут стараюсь, давайте делайте за меня в сё остальное». Ты бы ещё вот такое выложил

void setup(){}
void loop(){}

И сказал бы: «код, не пашет, помогите допилить».

mmc450 пишет:

Писать алгоритмы вручную??

Нет, сидеть ждать пока какой-нибудь добрый дядя за тебя напишет.

 

Я не прошу мне писать код, я прошу просто посоветовать в каком направлении смотреть.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

Ворота пишет:

 ты хоть пины сконфигурируй. 

так он все сделал кроме конфига пинов.. 

b707
Offline
Зарегистрирован: 26.05.2017

Ворота пишет:

Нет, сидеть ждать пока какой-нибудь добрый дядя за тебя напишет.

да ладно тебе, нормальный новичЕк, ни чета халявщикам - все ж таки что-то написал, правильно код вставил, не наглеет, вопросы грамотные задает.

sadman41
Offline
Зарегистрирован: 19.10.2016

mmc450 пишет:

Я не прошу мне писать код, я прошу просто посоветовать в каком направлении смотреть.

В направлении декомпозиции задачи. Например:

Проблема: обеспечить относительную неповторяемость ряда, генерируемого функцией random().
Решение: почитать про функцию randomSeed(), применять ее на каждом этапе/раунде/... игры.

mmc450
Offline
Зарегистрирован: 26.06.2018
#define LeUp 12
#define LeDo 10
#define RiUp 13
#define RiDo 11
int lot1 = 0;                       // Колличество выброшенных шариков
int lot2 = 0;                       // Колличество выброшенных шариков
int lot3 = 0;                       // Колличество выброшенных шариков
int lot4 = 0;                       // Колличество выброшенных шариков
int summ_lot = 0;                   // Сумма всех выброшенный шариков
int level = 0;                      // Уровень игры (скорость подачи шариков)
int kol_share = 50;                 // Колличество шариков в одном лотке

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
}

void vibros(int xr){                // функция открытия заслонки
  switch (xr) {
  case 1:
    if (lot1<kol_share) {           // не должно привышать максимальное колличество шариков в лотке
    digitalWrite(LeUp, HIGH);
    delay(level);
    digitalWrite(LeUp, LOW);
    delay (level);
    lot1 = ++lot1;}                 // прибавляем один выброшенный шарик
    break;
  case 2:
  if (lot2<kol_share) {
    digitalWrite(LeDo, HIGH);
    delay(level);
    digitalWrite(LeDo, LOW);
    delay (level);
    lot2 = ++lot2;}
    break;
  case 3:
  if (lot3<kol_share) {
    digitalWrite(RiUp, HIGH);
    delay(level);
    digitalWrite(RiUp, LOW);
    delay (level);
    lot3 = ++lot3;}
    break;
  case 4:
  if (lot4<kol_share) {
    digitalWrite(RiDo, HIGH);
    delay(level);
    digitalWrite(RiDo, LOW);
    delay (level);
    lot4 = ++lot4;}
    break;
}
}


void loop() {
summ_lot = lot1+lot2+lot3+lot4;               //Суммируем все шарики
if (summ_lot<10){                             // Выставляем уровень в зависимости от колличества выброшенных шариков
  level = 500;
}
if (summ_lot>10 && summ_lot<20){
  level = 150;
}


int lot_ran = random(analogRead(0));  
int x = random(lot_ran);
int y = map (x, 0, lot_ran, 1, 4);

Serial.println(lot_ran);
Serial.println(y);
Serial.println("            ");
vibros(y);
}

 

Получился сейчас вот такой код. Впринципе почти устраивает. Но как сделать так что бы не открывался более 2 раз один лоток? А то бывает и 4 раза выпадает одно и тоже число(

b707
Offline
Зарегистрирован: 26.05.2017

mmc450 пишет:

Но как сделать так что бы не открывался более 2 раз один лоток? А то бывает и 4 раза выпадает одно и тоже число(

на то это и случайная последовательность, что одно и то же число может по пять раз выпадать :) А иначе это уже не вполне случайность будет.

Зря вы в 68 строке map используете. Я ж написал - берите остаток от целочисленного деления на 4 - это и быстрее, и гарантировано только 4 варианта.

mmc450
Offline
Зарегистрирован: 26.06.2018

b707 пишет:

mmc450 пишет:

Но как сделать так что бы не открывался более 2 раз один лоток? А то бывает и 4 раза выпадает одно и тоже число(

на то это и случайная последовательность, что одно и то же число может по пять раз выпадать :) А иначе это уже не вполне случайность будет.

Зря вы в 68 строке map используете. Я ж написал - берите остаток от целочисленного деления на 4 - это и быстрее, и гарантировано только 4 варианта.

 

Можете пример привезти? не совсем понимаю как это организовать

mmc450
Offline
Зарегистрирован: 26.06.2018
#define LeUp 12
#define LeDo 10
#define RiUp 13
#define RiDo 11
int lot1 = 0;                       // Колличество выброшенных шариков
int lot2 = 0;                       // Колличество выброшенных шариков
int lot3 = 0;                       // Колличество выброшенных шариков
int lot4 = 0;                       // Колличество выброшенных шариков
int summ_lot = 0;                   // Сумма всех выброшенный шариков
int level = 0;                      // Уровень игры (скорость подачи шариков)
int kol_share = 50;                 // Колличество шариков в одном лотке

int y1 = 1;

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
}

void vibros(int xr){                // функция открытия заслонки
  switch (xr) {
  case 1:
    if (lot1<kol_share) {           // не должно привышать максимальное колличество шариков в лотке
    digitalWrite(LeUp, HIGH);
    delay(level);
    digitalWrite(LeUp, LOW);
    delay (level);
    lot1 = ++lot1;}                 // прибавляем один выброшенный шарик
    break;
  case 2:
  if (lot2<kol_share) {
    digitalWrite(LeDo, HIGH);
    delay(level);
    digitalWrite(LeDo, LOW);
    delay (level);
    lot2 = ++lot2;}
    break;
  case 3:
  if (lot3<kol_share) {
    digitalWrite(RiUp, HIGH);
    delay(level);
    digitalWrite(RiUp, LOW);
    delay (level);
    lot3 = ++lot3;}
    break;
  case 4:
  if (lot4<kol_share) {
    digitalWrite(RiDo, HIGH);
    delay(level);
    digitalWrite(RiDo, LOW);
    delay (level);
    lot4 = ++lot4;}
    break;
}
}


void loop() {
summ_lot = lot1+lot2+lot3+lot4;               //Суммируем все шарики
if (summ_lot<10){                             // Выставляем уровень в зависимости от колличества выброшенных шариков
  level = 500;
}
if (summ_lot>10 && summ_lot<20){
  level = 150;
}


int lot_ran = random(analogRead(0));  
int x = random(lot_ran);
int y = map (x, 0, lot_ran, 1, 5);

if (y != y1){

Serial.println(lot_ran);
Serial.println(y);
Serial.println("   ");
vibros(y);
y1=y;
}
}

добился методом сравнения что бы числа не повторялись, но будет хорошо если подскажите как сделать что бы были двойные повторения. А пока оставлю все как есть. По тихоньку буду дорабатывать. А пока жду актуаторы, и нажну собирать.

mmc450
Offline
Зарегистрирован: 26.06.2018

b707 пишет:

mmc450 пишет:

Но как сделать так что бы не открывался более 2 раз один лоток? А то бывает и 4 раза выпадает одно и тоже число(

на то это и случайная последовательность, что одно и то же число может по пять раз выпадать :) А иначе это уже не вполне случайность будет.

Зря вы в 68 строке map используете. Я ж написал - берите остаток от целочисленного деления на 4 - это и быстрее, и гарантировано только 4 варианта.

 

 

#define LeUp 12
#define LeDo 10
#define RiUp 13
#define RiDo 11
int lot1 = 0;                       // Колличество выброшенных шариков
int lot2 = 0;                       // Колличество выброшенных шариков
int lot3 = 0;                       // Колличество выброшенных шариков
int lot4 = 0;                       // Колличество выброшенных шариков
int summ_lot = 0;                   // Сумма всех выброшенный шариков
int level = 0;                      // Уровень игры (скорость подачи шариков)
int kol_share = 50;                 // Колличество шариков в одном лотке

int y1 = 1;

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
}

void vibros(int xr){                // функция открытия заслонки
  switch (xr) {
  case 1:
    if (lot1<kol_share) {           // не должно привышать максимальное колличество шариков в лотке
    digitalWrite(LeUp, HIGH);
    delay(level);
    digitalWrite(LeUp, LOW);
    delay (level);
    lot1 = ++lot1;}                 // прибавляем один выброшенный шарик
    break;
  case 2:
  if (lot2<kol_share) {
    digitalWrite(LeDo, HIGH);
    delay(level);
    digitalWrite(LeDo, LOW);
    delay (level);
    lot2 = ++lot2;}
    break;
  case 3:
  if (lot3<kol_share) {
    digitalWrite(RiUp, HIGH);
    delay(level);
    digitalWrite(RiUp, LOW);
    delay (level);
    lot3 = ++lot3;}
    break;
  case 4:
  if (lot4<kol_share) {
    digitalWrite(RiDo, HIGH);
    delay(level);
    digitalWrite(RiDo, LOW);
    delay (level);
    lot4 = ++lot4;}
    break;
}
}


void loop() {
summ_lot = lot1+lot2+lot3+lot4;               //Суммируем все шарики
if (summ_lot<10){                             // Выставляем уровень в зависимости от колличества выброшенных шариков
  level = 500;
}
if (summ_lot>10 && summ_lot<20){
  level = 150;
}


int lot_ran = random(analogRead(0));  
int x = random(lot_ran);
int y = x % 4;                   //= map (x, 0, lot_ran, 1, 5);

if (y != y1){

Serial.println(lot_ran);
Serial.println(y);
Serial.println("   ");
vibros(y);
y1=y;
}
}

так?

b707
Offline
Зарегистрирован: 26.05.2017

mmc450 пишет:

 

Можете пример привезти? не совсем понимаю как это организовать

ну блин... целочисленное деление

строку 68 заменить на

int y = x % 4;  // y от 0 до 3

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

b707 пишет:

mmc450 пишет:

 

Можете пример привезти? не совсем понимаю как это организовать

ну блин... целочисленное деление

строку 68 заменить на

int y = x % 4;  // y от 0 до 3

 

лучше уж 

int y = x & 0x03;

sadman41
Offline
Зарегистрирован: 19.10.2016

Зачем random() от random() вызывать - непонятно...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DetSimen пишет:

b707 пишет:

int y = x % 4;  // y от 0 до 3

лучше уж 

int y = x & 0x03;

Чем лучше?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

Ворота пишет:

void setup(){}
void loop(){}

Этот код как раз пашет на 100% ))

Блин, вроде и грамотный человек, надо ж такое ляпнуть. Хотя, конечно, со всеми бывает.

sadman41
Offline
Зарегистрирован: 19.10.2016

А что не так? Я его даже откомпилировал.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ЕвгенийП пишет:

DetSimen пишет:

b707 пишет:

int y = x % 4;  // y от 0 до 3

лучше уж 

int y = x & 0x03;

Чем лучше?

Согласен. С точки зрения компилятора - ничем не лучше. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

А что не так? Я его даже откомпилировал.

Надо было не только компилировать, но и запустить - попробовать.  У меня вот ардуина кодовым замком управляет. Загрузил - код набираю, а замку пофигу! Не пашет ни хрена!

Надо же когда-то объяснять новорождённым, что программа не бывает ни правильной, ни неправильной сама по себе, безотносительно решаемой задачи. Если задачу игнорировать, то в принципе любая программа 100% работает, т.к. процессор всегда что-то делает. Ни один еще не начал "делать ничего". Если мы с Вами не будем это постоянно талдычить, кто ж им это объяснит? В егэ такого нет.

sadman41
Offline
Зарегистрирован: 19.10.2016

А... извините. Не стал ардуину со стенда снимать, эксперимент идет. Но в следующий раз обязательно и залью и графики напряженности сниму.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Попробуйте так, за основу взял Ваш самый первый код, единственное что изменил - ПИНЫ

#define LeUp 2
#define LeDo 3
#define RiUp 4
#define RiDo 5
uint16_t sped = 500;//Начальная скорость
uint32_t time;//Фиксация времени
byte kolShar[4] = {10, 10, 10, 10};//4 ячейки по 10 шаров

void setup() {
  pinMode(LeUp, OUTPUT);
  pinMode(LeDo, OUTPUT);
  pinMode(RiUp, OUTPUT);
  pinMode(RiDo, OUTPUT);
}

void vibros(byte xr) {
//Проверяем чтобы небыло разрыва больше 3х шаров
  for (int i = 0; i < 4; i++)
  {
    if (kolShar[i] > kolShar[xr]) {
      if (kolShar[i] - kolShar[xr] > 2)xr = i;
    }
  }
// Если шаров в ячейке 0 смещаемся
  if (kolShar[xr] == 0) {
    for (int i = 0; i < 4; i++) {
      if (kolShar[i])xr = i;
    }
  }
  if (kolShar[xr] > 0) {
    kolShar[xr] = kolShar[xr] - 1;
  }

  switch (xr) {
    case 0:
      digitalWrite(LeUp, HIGH);
      delay(150);
      digitalWrite(LeUp, LOW);
      break;
    case 1:
      digitalWrite(LeDo, HIGH);
      delay(150);
      digitalWrite(LeDo, LOW);
      break;
    case 2:
      digitalWrite(RiUp, HIGH);
      delay(150);
      digitalWrite(RiUp, LOW);
      break;
    case 3:
      digitalWrite(RiDo, HIGH);
      delay(150);
      digitalWrite(RiDo, LOW);
      break;
  }
}

void loop() {
  int lot_ran = random(0, 4);
  if (millis() - time >= sped) //время бросать шар
  {
    byte summa = 0;
    time = millis();
    sped--; //Ускоряемся
    for (int i = 0; i < 4; i++) { //Если шары еще есть
      summa += kolShar[i];
    }
    if (summa > 0) vibros(lot_ran);// Идем в функцию броска
  }

}

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Небольшое дополнение
1- Для того чтобы была рандомность старта, необходимо добавить кнопку СТАРТ, тогда начало и игра будет каждый раз новая, Потому что после включения контролера рандом генерит числа а в какой момент Вы нажмете кнопку никому не извесно. И еще при каждой последующее игре скорость будет выше и выше.
2- Еще я бы поставил кнопку сброса или длинное нажатие кн. старт возвращало бы скорость в начальное состояние так как перезапускать контролер чтобы сбросить скорость не удобно, хотя и можно.
3- 63ю строку (time = millis();) надо перенести между 55 и 56 так как время фиксируется не коректно хотя и будет работать при условии что sped больше delay(150);