Vinnaren i pepparkakshustävlingen!
2017-09-08, 13:21
  #1
Medlem
Tjena!

Har en komplikation med min programmering, ska skriva kod med lysdioder så det blir olika mönster för varje gång man trycker på en knapp. Har kodat klart nu så allt funkar, men dessvärre med en delay så man inte kan byta mönster snabbt.

Så frågan är, hur kan man ersätta min delay med "Blink without delay"? Dvs. så det ej behövs en delay för att byta mönster.

Tack på förhand.
Citera
2017-09-08, 13:30
  #2
Medlem
Istället för en delay så kontrollerar du tiden som gått i din loop och när villkoret har uppfyllts så ändrar du state på din led.
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

Vi behöver nog se mer av din kod för att förstå vad som behöver ändras.
Citera
2017-09-08, 13:39
  #3
Medlem
Jo försökt kolla där men får ej alla lampor att följa mönstret.
Koden kan vara lite svår att läsa, ej renskriven.


Koden:

unsigned long previousMillis = 0;
const int i = LED_BUILTIN;

const long interval = 100;

char mode = 0;
boolean pressed = false;

void clearLEDs();
boolean checkButton();

void setup() {

pinMode(2, INPUT);
for(int i = 3; i < 14; i++)
{
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
}

void loop() {

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {

previousMillis = currentMillis;


}
if(mode == 0 || mode == 2)
{
for(int i = 13; i >= 3; i--)
{
if(checkButton() == true)
break;
digitalWrite(i, HIGH);
delay(100);
digitalWrite(i, LOW);
}
}
if(mode == 1 || mode == 2)
{
for(int i = 3; i <= 13; i++)
{
if(checkButton() == true)
break;
digitalWrite(i, HIGH);
delay(100);
digitalWrite(i, LOW);
}
}
}

void clearLEDs()
{
for(int i = 3; i < 14; i++)
digitalWrite(i, LOW);
}

boolean checkButton()
{ char state = digitalRead(2);
if(state == HIGH && pressed == false)
{
pressed = true;
return false;
}
if(state == LOW && pressed == true)
{
mode++;
if(mode > 2)
mode = 0;
clearLEDs();
pressed = false;
return true;
}
return false;
}
Citera
2017-09-08, 13:50
  #4
Medlem
Inom PHP-taggar så det blir läsbart:
Kod:
unsigned long previousMillis 0;
const 
int i =  LED_BUILTIN;

const 
long interval 100;

char mode 0;
boolean pressed false;

void clearLEDs();
boolean checkButton();

void setup() {

  
pinMode(2INPUT);
  for (
int i 314i++)
  {
    
pinMode(iOUTPUT);
    
digitalWrite(iLOW);
  }
}

void loop() {

  
unsigned long currentMillis millis();

  if (
currentMillis previousMillis >= interval) {

    
previousMillis currentMillis;


  }
  if (
mode == || mode == 2)
  {
    for (
int i 13>= 3i--)
    {
      if (
checkButton() == true)
        break;
      
digitalWrite(iHIGH);
      
delay(100);
      
digitalWrite(iLOW);
    }
  }
  if (
mode == || mode == 2)
  {
    for (
int i 3<= 13i++)
    {
      if (
checkButton() == true)
        break;
      
digitalWrite(iHIGH);
      
delay(100);
      
digitalWrite(iLOW);
    }
  }
}

void clearLEDs()
{
  for (
int i 314i++)
    
digitalWrite(iLOW);
}

boolean checkButton() {
  
char state digitalRead(2);
  if (
state == HIGH && pressed == false)
  {
    
pressed true;
    return 
false;
  }
  if (
state == LOW && pressed == true)
  {
    
mode++;
    if (
mode 2)
      
mode 0;
    
clearLEDs();
    
pressed false;
    return 
true;
  }
  return 
false;

__________________
Senast redigerad av e7andy 2017-09-08 kl. 13:55.
Citera
2017-09-08, 13:52
  #5
Medlem
Citat:
Ursprungligen postat av e7andy
Istället för en delay så kontrollerar du tiden som gått i din loop och när villkoret har uppfyllts så ändrar du state på din led.
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

Vi behöver nog se mer av din kod för att förstå vad som behöver ändras.

Jo försökt kolla där men får ej alla lampor att följa mönstret.
Koden kan vara lite svår att läsa, ej renskriven.


Koden:

unsigned long previousMillis = 0;
const int i = LED_BUILTIN;

const long interval = 100;

char mode = 0;
boolean pressed = false;

void clearLEDs();
boolean checkButton();

void setup() {

pinMode(2, INPUT);
for(int i = 3; i < 14; i++)
{
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
}

void loop() {

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {

previousMillis = currentMillis;


}
if(mode == 0 || mode == 2)
{
for(int i = 13; i >= 3; i--)
{
if(checkButton() == true)
break;
digitalWrite(i, HIGH);
delay(100);
digitalWrite(i, LOW);
}
}
if(mode == 1 || mode == 2)
{
for(int i = 3; i <= 13; i++)
{
if(checkButton() == true)
break;
digitalWrite(i, HIGH);
delay(100);
digitalWrite(i, LOW);
}
}
}

void clearLEDs()
{
for(int i = 3; i < 14; i++)
digitalWrite(i, LOW);
}

boolean checkButton()
{ char state = digitalRead(2);
if(state == HIGH && pressed == false)
{
pressed = true;
return false;
}
if(state == LOW && pressed == true)
{
mode++;
if(mode > 2)
mode = 0;
clearLEDs();
pressed = false;
return true;
}
return false;
}
Citera
2017-09-08, 13:55
  #6
Medlem
Citat:
Ursprungligen postat av e7andy
Inom PHP-taggar så det blir läsbart:
Kod:
unsigned long previousMillis 0;        
const 
int i =  LED_BUILTIN;

const 
long interval 100;     

      
char mode 0;
boolean pressed false;

void clearLEDs();
boolean checkButton();

void setup() {
  
  
pinMode(2INPUT);
  for(
int i 314i++)
  {
    
pinMode(iOUTPUT);
    
digitalWrite(iLOW);
  }
}

void loop() {

  
unsigned long currentMillis millis();

  if (
currentMillis previousMillis >= interval) {
    
    
previousMillis currentMillis;


  }
    if(
mode == || mode == 2)
  {
    for(
int i 13>= 3i--)
    {
      if(
checkButton() == true)
        break;
      
digitalWrite(iHIGH);
      
delay(100);
      
digitalWrite(iLOW);
    }
  }
  if(
mode == || mode == 2)
  {
    for(
int i 3<= 13i++)
    {
      if(
checkButton() == true)
        break;
      
digitalWrite(iHIGH);
      
delay(100);
      
digitalWrite(iLOW);
    }
  }
}

void clearLEDs()
{
  for(
int i 314i++)
    
digitalWrite(iLOW);
}

boolean checkButton()
{  
char state digitalRead(2);
  if(
state == HIGH && pressed == false)
  {
    
pressed true;
    return 
false;
  }
  if(
state == LOW && pressed == true)
  {
    
mode++;
    if(
mode 2)
      
mode 0;
    
clearLEDs();
    
pressed false;
    return 
true;
  }
  return 
false;


Jo, det är dock delayen som är problemet. Går den att ersätta, eller behöver man koda om allt?
Citera
2017-09-08, 14:07
  #7
Medlem
Citat:
Ursprungligen postat av viggejonsson
Jo, det är dock delayen som är problemet. Går den att ersätta, eller behöver man koda om allt?
Ja precis. Delayen är problemet. Arduino har ingen trådning (även om det verkar gå på något sätt, men inte helt självklart) så man kan inte göra saker parallellt. Man får istället hantera allt i loop vilket skapar vissa svårigheter. Jag tror man får koda om en hel del.

Du får istället kolla på tiden och se när ett tidsintervall har uppnåtts. När tidsintervallet har uppnåtts så ändrar du state på dina led:ar.

Kod:
unsigned long currentMillis millis();

if (
currentMillis previousMillis >= interval) {
  
previousMillis currentMillis;
  
  
// Gör ändringar av state


För att direkt byta mönster när det sker så lägger du även in en kontroll av det i if-satsen. Typ något sånt här:
Kod:
if (currentMillis previousMillis >= interval  || isButtonPressed()) { 
I varje varv i loopen så kontrolleras dels om tidsintervallet ("delayen") har uppfyllts och dels om knappen är intryckt.

Jag förstår inte helt hur din kod fungerar så jag gissar lite vad som gör vad och hur jag tror du tänkt att det ska fungera.
__________________
Senast redigerad av e7andy 2017-09-08 kl. 14:09.
Citera
2017-09-08, 14:17
  #8
Medlem
Citat:
Ursprungligen postat av e7andy
Ja precis. Delayen är problemet. Arduino har ingen trådning (även om det verkar gå på något sätt, men inte helt självklart) så man kan inte göra saker parallellt. Man får istället hantera allt i loop vilket skapar vissa svårigheter. Jag tror man får koda om en hel del.

Du får istället kolla på tiden och se när ett tidsintervall har uppnåtts. När tidsintervallet har uppnåtts så ändrar du state på dina led:ar.

Kod:
unsigned long currentMillis millis();

if (
currentMillis previousMillis >= interval) {
  
previousMillis currentMillis;
  
  
// Gör ändringar av state


För att direkt byta mönster när det sker så lägger du även in en kontroll av det i if-satsen. Typ något sånt här:
Kod:
if (currentMillis previousMillis >= interval  || isButtonPressed()) { 
I varje varv i loopen så kontrolleras dels om tidsintervallet ("delayen") har uppfyllts och dels om knappen är intryckt.

Jag förstår inte helt hur din kod fungerar så jag gissar lite vad som gör vad och hur jag tror du tänkt att det ska fungera.

Började med arduino för någon vecka sen, så är lite seg.
Kan du ge något exempel för typ ett knapptryck så lysdioderna funkar utan delay? Vet inte riktigt hur jag ska forstsätta.
Citera
2017-09-08, 19:04
  #9
Medlem
Citat:
Ursprungligen postat av viggejonsson
Började med arduino för någon vecka sen, så är lite seg.
Kan du ge något exempel för typ ett knapptryck så lysdioderna funkar utan delay? Vet inte riktigt hur jag ska forstsätta.
Börja med så enkla saker som möjligt som i exemplet här: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
Sen kan du bygga ut den med fler dioder.

Jag förstår inte hur du tänker göra mönster med din kod. Just nu verkar den mest tända eller släcka alla. Om man ska göra något typ av mönster med dioderna så behöver man tända och släcka dem olika beroende på vilken diod det är och då behöver man spara ner mönstren på något sätt och sen använda det för att styra dem rätt.
Citera
2017-09-08, 21:28
  #10
Medlem
Citat:
Ursprungligen postat av e7andy
Börja med så enkla saker som möjligt som i exemplet här: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
Sen kan du bygga ut den med fler dioder.

Jag förstår inte hur du tänker göra mönster med din kod. Just nu verkar den mest tända eller släcka alla. Om man ska göra något typ av mönster med dioderna så behöver man tända och släcka dem olika beroende på vilken diod det är och då behöver man spara ner mönstren på något sätt och sen använda det för att styra dem rätt.
Nu kom jag på att du nog får ett rinnande mönster där varje diod tänds och släcks efter varandra. Eftersom du vänder på räknaren så ska det rinna åt olika håll när du trycker in en knapp.
Citera
2017-09-09, 09:24
  #11
Moderator
vhes avatar
Övriga språk --> C, C++ och assembler
/Moderator
Citera
2017-12-04, 01:37
  #12
Medlem
Kod:
int mode = 1;
int state = 1;
int pin = 3;
unsigned long prev_ms = 0;

void loop()
{
unsigned long ms = millis();
if(ms - prev_ms >= 100) {
digitalWrite(pin, state);
state = !state;
if(state)
  pin += mode;
if(pin >= 13)
  pin = 3;
if(pin < 3)
  pin = 13;
prev_ms = ms;
}

}

Nånting så där kanske. mode i det här fallet ska togglas mellan 1 och -1 när du trycker på knappen, så den koden får du lägga till själv.

borde få en rad dioder kopplade på pins 3 - 13 att lysa upp och släckas sekventiellt åt ena eller andra hållet med 100ms intervall.
Du ska kunna ändra riktning direkt. Helt otestad kod skriven på mobilen, men det borde peka dig i rätt riktning iaf
__________________
Senast redigerad av masterflex22 2017-12-04 kl. 01:41. Anledning: fel i koden
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback