Problem med interupt Uno32

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
SeniorLemuren
Inlägg: 7812
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Problem med interupt Uno32

Inlägg av SeniorLemuren »

Jag vill köra en stegmotor med AccelStepper och samtidigt räkna pulser från en optogivare. Jag använder en chipKit Uno32 till detta. Jag har gjort ett program som använder Accelstepper för att köra stegmotorn och samtidigt använder jag en interupt pinne för att ta in pulserna. I programmet blinkar jag en led för att se att pulser kommer in,

Avbrottsrutinen fungerar inte så länge motorn snurrar

Kod: Markera allt

stepper.runToNewPosition(20000);
När den stoppar så fungerar avbrottsrutinen. Vad gör jag för fel?

Kod: Markera allt

volatile boolean LEDstate = false; // To make sure variables shared between an ISR
//the main program are updated correctly,declare them as volatile.

#include <AccelStepper.h>
#define dirPin 3
#define stepPin 4

#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
stepper.setMaxSpeed(5000);
stepper.setAcceleration(1000);

pinMode(PIN_LED1, OUTPUT); //set pin 13 as output
attachInterrupt(3, LEDchange, FALLING); // avbrottsrutin 3 på pinne 7
}

void loop() {
digitalWrite(PIN_LED1, LEDstate); //pin 13 equal the state value 

stepper.runToNewPosition(20000);
}

void LEDchange() { 
  // ISR function
   LEDstate = !LEDstate; //toggle the state when the interrupt occurs
}
ToPNoTCH
Inlägg: 4892
Blev medlem: 21 december 2009, 17:59:48

Re: Problem med interupt Uno32

Inlägg av ToPNoTCH »

Kollar man i dokumentationen finnar man:
Moves the motor (with acceleration/deceleration) to the new target position and blocks until it is at position. Dont use this in event loops, since it blocks.
Om du kör
run()
i main loopen istället borde det funka.

Du måste du givetvis sätta targetPosition() till 20000 (i ditt fall) i void setup.
SeniorLemuren
Inlägg: 7812
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Problem med interupt Uno32

Inlägg av SeniorLemuren »

Kannon. Nu funkar det. :tumupp:
Användarvisningsbild
Klas-Kenny
Inlägg: 11351
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Problem med interupt Uno32

Inlägg av Klas-Kenny »

Grejen är inte att interruptet inte körs.
Grejen är att interruptet uppdaterar LEDstate, men det ändrar inte utgången förrän nästa varv i loopen (nästa digitalWrite() ).

Flytta digitalWrite() till att köras ifrån interruptet så ska du se att det fungerar oavsett vad du gör i loop().
SeniorLemuren
Inlägg: 7812
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Problem med interupt Uno32

Inlägg av SeniorLemuren »

Ok. Men jag vill ju inte låsa loopen, ska göra lite mer i den, så jag kör så här nu och det funkar bra.

Kod: Markera allt

volatile boolean LEDstate = false; // To make sure variables shared between an ISR
//the main program are updated correctly,declare them as volatile.

#include <AccelStepper.h>
#define dirPin 3
#define stepPin 4

#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
stepper.setMaxSpeed(5000);
stepper.setAcceleration(1000);
stepper.moveTo(10000000);

pinMode(PIN_LED1, OUTPUT); //set pin 13 as output

attachInterrupt(3, LEDchange, FALLING);
}

void loop() {
digitalWrite(PIN_LED1, LEDstate); //pin 13 equal the state value 

stepper.run();
}

void LEDchange() { 
  // ISR function
   LEDstate = !LEDstate; //toggle the state when the interrupt occurs
}
Användarvisningsbild
hawkan
Inlägg: 2637
Blev medlem: 14 augusti 2011, 10:27:40

Re: Problem med interupt Uno32

Inlägg av hawkan »

Det råkar fungera. Klas-Kennys inlägg ska tas seriöst.
Släng bort LEDState. Utgången vet själv sitt tillstånd. Byt ut din Isr till

Kod: Markera allt

void LEDchange() { 
  // ISR function
  digitalWrite(PIN_LED1, !digitalRead(PIN_LED1));
}
agehall
Inlägg: 427
Blev medlem: 12 augusti 2020, 19:27:54

Re: Problem med interupt Uno32

Inlägg av agehall »

Nu är ju det stora misstaget att använda Arduino’s SW-platform, men att flytta DigitalWrite() till en ISR gör inte saken bättre. Det är helt rätt att göra så lite som möjligt i en ISR och sedan göra det tunga jobbet utanför.
Användarvisningsbild
Klas-Kenny
Inlägg: 11351
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Problem med interupt Uno32

Inlägg av Klas-Kenny »

Vad som är "rätt" och vad som är "fel" beror ju helt på applikationen.

Är det viktigt att utgången sätta "direkt", gör det ifrån interruptet. Sätts den tillräckligt snabbt även om man behöver vänta upp till ett helt varv i loopen, så har det sina fördelar att skriva därifrån. Och hur mycket som är okej att göra ifrån ett interrupt beror ju också helt på applikationen, hur länge det tål att uppehållas.
Att sätta en utgång är till 99.9% inte för mycket, med rimligt effektiv kod (vet inte hur effektivt digitalWrite är implementerat) så tar det inte mycket längre tid än att bara skriva en variabel.


Jag ville mest beskriva VARFÖR det inte fungerade först, och varför Run() fungerar. Förklaringen att runToNewPosition() är blockerande är bara en del av sanningen. Den blockerar nämligen inte några interrupt, som TS tycktes tro var det som hände.
Viktigt skillnad.
Användarvisningsbild
hawkan
Inlägg: 2637
Blev medlem: 14 augusti 2011, 10:27:40

Re: Problem med interupt Uno32

Inlägg av hawkan »

Att läsa och skriva en pinne är knappast för mycket i en isr, det är istället mycket lämpligt i detta fallet.
Det gör led-blinkandet helt fristående från applikationen och TS kan gå tillbaka till att positionera stegmotorerna
utan att strössla koden med digitalWritear. Leden blinkar när den ska.
SeniorLemuren
Inlägg: 7812
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Problem med interupt Uno32

Inlägg av SeniorLemuren »

Att blinka dioden är inte det huvudsakliga. Det var bara en test för att se om den skiva jag använder har tillräckligt stora slitsar för att generera stabila pulser.

Funktionen av det hela skall vara att ta emot pulser från 2 stegmotorer och kontrollera att de får samma antal pulser hela tiden. Detta är en alternativ lösning till det som diskuterades i tråden om att använda closed loop drivers till Y-motorerna på CNC-fräsen för att få stopp om den ena motorn kommer efter.

Så det saknas en hel del i programmet och som någon tidigare påpekade så strävar jag efter att lägga så lite som möjligt i avbrottsrutinen.
SeniorLemuren
Inlägg: 7812
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Problem med interupt Uno32

Inlägg av SeniorLemuren »

agehall skrev: 1 april 2024, 08:37:15 Nu är ju det stora misstaget att använda Arduino’s SW-platform, men att flytta DigitalWrite() till en ISR gör inte saken bättre. Det är helt rätt att göra så lite som möjligt i en ISR och sedan göra det tunga jobbet utanför.
Vilken plattform använder du till Digilent ChipKit Uno32?
SeniorLemuren
Inlägg: 7812
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Problem med interupt Uno32

Inlägg av SeniorLemuren »

ToPNoTCH skrev: 31 mars 2024, 19:49:09 Kollar man i dokumentationen finnar man:
Moves the motor (with acceleration/deceleration) to the new target position and blocks until it is at position. Dont use this in event loops, since it blocks.
Om du kör
run()
i main loopen istället borde det funka.

Du måste du givetvis sätta targetPosition() till 20000 (i ditt fall) i void setup.
Har du en länk till vilken dokumentation du fann denna information. Jag letar nämligen efter varför CHANGE i interruptrutinen inte fungerar. RISING och FALLING är inga problem.
Användarvisningsbild
Klas-Kenny
Inlägg: 11351
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Problem med interupt Uno32

Inlägg av Klas-Kenny »

All dokumentation finns här:
https://www.arduino.cc/reference/en/

Just det för AccelStepper finns här:
https://www.arduino.cc/reference/en/lib ... elstepper/
Letar man sig vidare där kommer man till sist hit:
https://www.airspayce.com/mikem/arduino ... e39a6f0e67
SeniorLemuren
Inlägg: 7812
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Problem med interupt Uno32

Inlägg av SeniorLemuren »

Tack. Men problemet är att jag inte använder Arduino utan chipKIT Digilent UNO32 som skiljer en hel del från Arduino
Microchip® PIC32MX320F128H microcontroller (80 Mhz 32-bit MIPS, 128K Flash, 16K SRAM) Det är interruptpinnarna jag vill veta mer om. Jag letar efter varför CHANGE i interruptrutinen inte fungerar. RISING och FALLING är inga problem. Kan ju tänkas vara skillnader där jämfört med Arduino
Användarvisningsbild
Klas-Kenny
Inlägg: 11351
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Problem med interupt Uno32

Inlägg av Klas-Kenny »

Då är du på lite smått hal is vad gäller dokumentation och allmänt stöd för vissa "specialgrejer".

Hittade källkoden,
https://github.com/chipKIT32/chipKIT-co ... upts.c#L71

Verkar som att man bara implementerat pin-interrupt via de specifika interrupt-pinnarna, som jag inte tror har stöd för interrupt-on-change utan bara vid antingen uppåtgående, eller nedåtgående flank. (Koden som sätter upp interruptet kollar till och med uttryckligen att mode != CHANGE, annars hoppar den över alltihop)
Hårdvaran stödjer "change notification" som kan ge interrupt vid godtycklig förändring på de flesta I/O, men det ger ett enda interrupt som man sen själv får kontrollera vilken av pinnarna som orsakade det. Osäker på hur man implementerar godtyckliga interrupt i Arduino-världen, men det går säkert googla sig till ifall man vill gå den vägen.
Skriv svar