Arduino schéma - arduino.sk

Attachinterrupt

Vaše nápady a pomoc s Vašimi projektami
Príspevky: 8
Registrovaný: Pon 16. Mar 2015 19:25:57

Attachinterrupt

Poslaťod Narex » Ned 20. Sep 2015 21:47:01

Zdravím.
Robím ovládanie krokového motora pomocou joysticku, k tomu počitadlo impulzov s indukčnym snimačom a lcd displejom 16x2.
Všetko samostatne funguje, no ako som to dal do kopy, tak po spustení programu snimač reaguje na impulzy, super... aj ovladanie motora cez joystick funguje(velkostou uhlu výkyvu joysticku regulujem rychlosť) no akonáhle zase začnem dávať impulzy na snímači, tak už nereaguje, proste nepočíta ale ovládanie krokového motora funguje. Driver pre krokový motor je HY-DIV268N-5A

Vedel by niekto, kde je chyba? Program je zatial neupravený.

Ďakujem

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
//Arduino Sketch based on easy driver
int half_revolutions = 1;

int rpm = 0;
unsigned long lastmillis = 0;
int cislo=56;

int dirpin = 8;
int steppin = 9;
int enable = 7;

int ledPin = 13;
int joyPin1 = 0; // slider variable connecetd to analog pin 0
int joyPin2 = 1; // slider variable connecetd to analog pin 1
int value1 = 0; // variable to read the value from the analog pin 0
int value2 = 0;

int polohapin = 2;
int nastaveniepin = 3;
int nastavenie;
int poloha;
int motorSpeedright;
int motorSpeedleft;

void setup()
{
lcd.begin(16,2);
pinMode(dirpin, OUTPUT);
pinMode(steppin, OUTPUT);
digitalWrite(enable, HIGH);
Serial.begin(9600);
attachInterrupt(0, rpm_fan, RISING);
//lcd.setCursor(0,0);
//lcd.print("hello, world!");

}

//int treatValue(int data) {
//return (data * 9 / 1024) + 48;}


void loop()
{


int i;

value1 = analogRead(joyPin1);
//Serial.println(value1);

//nastavenie = analogRead(nastaveniepin);
poloha = analogRead(polohapin);

//Serial.println(nastavenie);

int poloha1 = map(poloha, 0, 1023, 0, 100);
//Serial.println(poloha1);


if(value1>540){
/*if(poloha1>95){ motorSpeedright=0;}
else{*/
value1 = analogRead(joyPin1);
motorSpeedright = map(value1, 512, 1023, 800, 400);
digitalWrite(dirpin, HIGH); // Set the direction.
//delay(1000);
for (i = 0; i<40; i++) // Iterate for 4000 microsteps.
{
digitalWrite(steppin, LOW); // This LOW to HIGH change is what creates the
delayMicroseconds(motorSpeedright);
digitalWrite(steppin, HIGH);
delayMicroseconds(motorSpeedright); // This delay time is close to top speed for this
}} // particular motor. Any faster the motor stalls.
//}


if(value1<500){
/*if(poloha1<5){ motorSpeedleft=0;}
else{*/
value1 = analogRead(joyPin1);
motorSpeedleft = map(value1, 0, 512, 400, 800);
digitalWrite(dirpin, LOW); // Change direction.

for (i = 0; i<40; i++) // Iterate for 4000 microsteps
{
digitalWrite(steppin, LOW); // This LOW to HIGH change is what creates the
delayMicroseconds(motorSpeedleft);
digitalWrite(steppin, HIGH);
delayMicroseconds(motorSpeedleft); // This delay time is close to top speed for this
//}
}
}// particular motor. Any faster the motor stalls.

if (millis() - lastmillis == 300){ //Uptade every one second, this will be equal to reading frecuency (Hz).

detachInterrupt(0);//Disable interrupt when calculating

rpm = half_revolutions ; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.

//Serial.print("RPM =\t"); //print the word "RPM" and tab.
//Serial.println(rpm); // print the rpm value.
lcd.setCursor(0,0);
lcd.print(rpm);
// Serial.print("\t Hz=\t"); //print the word "Hz".
//Serial.println(half_revolutions); //print revolutions per second or Hz. And print new line or enter.


lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, RISING); //enable interrupt
}

}

void rpm_fan(){
half_revolutions++;
}

Príspevky: 74
Registrovaný: Štv 04. Dec 2014 22:15:58
Bydlisko: Banská Bystrica

Re: Attachinterrupt

Poslaťod Robo Ulbricht » Pon 21. Sep 2015 10:00:40

Kód "if (millis() - lastmillis == 300)" je trošku podozrivý. Predpokladá, že nastane udalosť úplne presne na milisekundy. Tam to mohlo zahaprovať a výsledok odčítania mohol byť aj 298, 299, 301, ...

Druhé podozrivé miesto je "int half_revolutions = 1;". Vo vnútri prerušení, ak chceme komunikovať so zvyškom programu, tak sa premenná označuje "volatile int ". To preto, aby kompilátor neoptimalizoval samotnú premennú do registra a potom obe časti programu môže čítať rozdielne hodnoty.

Príspevky: 174
Registrovaný: Ned 16. Mar 2014 23:22:00

Re: Attachinterrupt

Poslaťod posjirka » Uto 22. Sep 2015 18:35:26

nelibi se mi
detachInterrupt(0);//Disable interrupt when calculating
já bych přerušení nevypínal, ale hned zresetoval promennou a nech to žít vlastním životem
a

if (millis() - lastmillis == 300){ //Uptade every one second, this will be equal to reading frecuency (Hz).
Tady bych použil další pár závorek jinak nevím co to udělá ... spíš pro jistotu uzavřít (millis() - lastmillis) takto do závorek
Navíc použít == je holý nesmysl. Nikdy se netrefíš přesně do 300 ms. použij "<"

if ((millis() - lastmillis) > 300){ //Uptade every one second, this will be equal to reading frecuency (Hz).

Príspevky: 8
Registrovaný: Pon 16. Mar 2015 19:25:57

Re: Attachinterrupt

Poslaťod Narex » Uto 22. Sep 2015 22:11:57

Jasné, všetko som poopravoval v programe, no ešte som ho neskúšal na konkretnom zapojení. To == bolo použité v programe k počítadlu impulzov, tak som to prehliadol. Vyskúšam a napíšem ;)

Späť na Projekty vo fáze vývoja