Ciao
Sono alle prese con una applicazione che prevede la lettura di un encoder allegato tipo CWZ6C, ho un segnale quadrato controllato con oscilloscopio, devo migliorare la forma del segnale in uscita dal fotoaccoppiatore 4N32 che è pessimo, allego l'immagine del segnale e lo schema completo che sto utilizzando. Il tutto serve a controllare un motore stepper, potrebbe essere il motore a creare i disturbi?
ciao
l'encoder può essere alimentato anche a 5v ma nell'applicazione le altre tensioni sono a 12v, era per avere una sola tensione, cerco quello che mi hai indicato.
Grazie
Stefano
se la velocità è il problema (quindi devi usare opo veloci) ricorda che ci son integrati come il7414 che son trigger di shmit che puoi interporre tra opto ed arduino, nel caso servisse!
Il tuo encoder è con uscite open collector, questo significa che puoi avere 2 tensioni distinte come alimentazione encoder=12VDC e livello di uscita=5VDC, leva il fotoaccoppiatore e metti una resistenza da 1Kohm tra uscita A e +5VDC, e un'altra resistenza tra uscita B e +5VDC , usa un cavo schermato, se l'encoder dista da arduino al massimo 2-3 metri non avrai problemi
ciao
si vede che ci capisco veramente poco, ho seguito schemi trovati in rete, l'uso del fotoaccopiatore mi piaceva per proteggere l'arduino da problemi a monte. @matinix il 7414 lo conosco e la velocità non è un problema @icio ma c'e una tensione minima di 2v, ho provato con lo schema ma non funziona il conteggio degli impulsi
Vi descrivo l'applicazione:
devo fare ruotare un tamburo di un certo angolo, da un lato ho un motore stepper collegato al tamburo con una puleggia, dall'altro questo encoder da 360 impulsi/giro, un arduino è collegato all'encoder per usare la funzione interrupt, mentre un altro arduino è collegato attraverso un driver al motore. Questo è lo sketch.
/*
per trapianto_stepper_test_31
gestisce il segnale dell'encoder
utilizzo di un encoder NPN
scheda 7/10
*/
#define encoder_PinA 2
#define motor_Pin 12
#define motor_led 13
volatile long angolo;
long angolo_1;
long angolo_k;
byte fila;
long k;
long i;
void setup()
{
Serial.begin(9600);
pinMode(encoder_PinA, INPUT_PULLUP);
attachInterrupt(0, canaleA, RISING); //encoder al pin 2
angolo = 0;
angolo_1 = 0;
angolo_k = 100;
fila = 1;
k = 1;
i = 1;
/* Serial.print("k");
Serial.print('\t');
Serial.println("angolo");*/
pinMode(motor_Pin, OUTPUT);
pinMode(motor_led, OUTPUT);
digitalWrite(motor_Pin, LOW);
digitalWrite(motor_led, HIGH);
delay(1000);
//Serial.println("Pronto");
}
void loop()
{
while(k == i)
{
i++;
angolo_1 = angolo_k * k;
switch(fila)
{
case 1:
digitalWrite(motor_Pin, LOW);
digitalWrite(motor_led, LOW);
//Serial.println(digitalRead(motor_Pin));
fila = 2;
break;
case 2:
digitalWrite(motor_Pin, HIGH);
digitalWrite(motor_led, HIGH);
fila = 1;
// Serial.println(digitalRead(motor_Pin));
break;
}
Serial.println(k);
Serial.println(angolo);
Serial.println(angolo_1);
}
if(angolo == angolo_1)
{
k++;
}
}
void canaleA()
{
angolo++;
}
ciao
ho migliorato, l'uscita dell'opto verso arduino, mettendo una R2 10k e una R3 tra base e gnd da 1M, adesso ho un problema con lo sketch che, dopo un certo numero di conteggi si ferma, ultriore osservazione è che questo numero è variabile, come al solito chiedo suggerimenti
Ho capito bene cosa significa open collector, ho collegato arduino+encoder ma stavolta è il driver dello stepper a dare problemi, in qualche modo interferisce con la scheda
l'univca cosa che capisco è che ci son 3 alimentazioni (+5vcc, +12Vcc, +24vcc) ma nessuna informazione su chi le da, come son legate tra loro da dove provvengono ecc ecc ecc.
in più hai fatto una stima (almeno) della corrente necessaria a tenere in piedi tutto??
dalla rete 220v
+24v alimentatore collegato al V+ del driver
GND alimentatore collegato al GND del driver
dalla rete 220v
+9v alimentatore per il primo e secondo arduino
pull+ del driver collegato al +5v del secondo arduino
pull- del driver collegato al pin 12 del secondo arduino
+5v del primo arduino collegato al V+ dell'encoder e a una estremità di una resistenza da 10k
pin 2 collegato all'altra estremità della resistenza da 10k e al segnale dell'encoder
GND collegato al GND dell'encoder
quello che non capisco è perchè il secondo arduino collegato all'encoder funziona solo con il driver non alimentato
oggi ho acquistato dei cavi schermati vediamo se la cosa migliora
ciao @martinix come sospettavi c'erano problemi di alimentazione con l'alimentatore (il solito cinese) di arduino, le masse sono tutte in comune con lo schermo dei cavi a massa solo da un lato
il tutto è migliorato ma ancora non funziona allego l'onda dell'encoder e l'onda al pin 12 e qualche foto, nello sketch,
/*
per trapianto_stepper_test_31
gestisce il segnale dell'encoder
utilizzo di un encoder NPN
scheda 7/10
*/
#define encoder_PinA 2
#define motor_Pin 12
#define motor_led 13
volatile long angolo;
long angolo_k;
byte fila;
long k;
long i;
void setup()
{
Serial.begin(9600);
pinMode(encoder_PinA, INPUT);
attachInterrupt(0, canaleA, RISING); //encoder al pin 2
angolo = 0;
angolo_k = 100;
fila = 1;
k = 1;
i = 1;
pinMode(motor_Pin, OUTPUT);
pinMode(motor_led, OUTPUT);
digitalWrite(motor_Pin, LOW);
digitalWrite(motor_led, LOW);
delay(1000);
//Serial.println("Pronto");
}
void loop()
{
while(k == i)
{
i++;
switch(fila)
{
case 1:
digitalWrite(motor_Pin, HIGH);
digitalWrite(motor_led, HIGH);
//Serial.println(digitalRead(motor_Pin));
fila = 2;
break;
case 2:
digitalWrite(motor_Pin, LOW);
digitalWrite(motor_led, LOW);
fila = 1;
// Serial.println(digitalRead(motor_Pin));
break;
}
//Serial.print(k);
//Serial.print('\t');
//Serial.println(i);
//Serial.println(angolo);
// Serial.println(angolo_1);
}
}
void canaleA()
{
angolo++;
if(angolo == angolo_k * k)
{
k++;
}
}
viene continuamente eseguito mentre dovrebbe essere eseguito ogni qualvolta
ciao
le prove continuano, ma senza risultato ho fatto una modifica allo sketch che legge l'encoder ma senza risultato, allora ho provato contando il numero di passi dello stepper ma il posizionamento non è regolare forse perde passi, ma ne la coppia resistente e la velocità di rotazione non sono elevate, 0.2 kg*cm e 1 giro/sec.
Capisco che arduino abbia dei limiti, ma l'applicazione non mi sembra esasperata, considerando il fatto che il conteggio degli impulsi dell'encoder a tavolino funziona bene. La presenza dello stepper nei paraggi crea problemi.
a questo punto (se non ci son altre idee) bisognerebbe analizzare un pò tutti i segnali con le nuove modifiche, oltre che i segnali del encoder, anche quelli di uscita di arduino e le alimentazioni, per vedere se entrano disturbi o altro!
ciao
dopo diverse prove e consigli, la situazione è migliorata, resta da risolvere il non trascurabile dettaglio dell'errato posizionamento, cerco di recuperare un opto più veloce come consigliato
ciao
ho risolto in parte il problema del posizionamento dello stepper, eliminando l'encoder e contando i passi del motore, pero' adesso si presenta uno strano comportamento, che provo a descrivere:
quando il motore si arresta a grazie a un sensore collegato al pin 3 e monitorato dall'interrupt in modalità FALLING, talvolta succede che dopo l'arresto il motore trascorso l'intervallo stabilito ruoti di qualche passo per arrestarsi e riprendere a muoversi regolarmente dopo il medesimo tempo, in pratica succede questo
STOP-MOTO-STOP-MOTO fino al prossimo stop
mentre dovrebbe fare questo
STOP-MOTO fino al prossimo stop
Credo che il comportamento sia anche corretto, perchè dipende da dove l'interrupt riprende il programma, ho quindi provato a mettere un goto dentro l'interrupt per rimandare il programma all'inizio, ma il compilatore non lo accetta
lo sketch che uso:
/*
by Nick Gammon per debounce
*/
const byte switchPin = 11;
byte oldSwitchState = HIGH; // assume switch open because of pull-up resistor
const unsigned long debounceTime = 5; // milliseconds
unsigned long switchPressTime; // when the switch last changed state
byte switchState;
#define led_pin 13
#define sensor_stop_pin 3
#define motorPin 12// digital pin per il driver dello stepper
int ritardo, ritardo_1;
volatile byte k;
byte pin;
void setup()
{
pinMode (led_pin, OUTPUT);
pinMode (switchPin, INPUT_PULLUP);
pinMode(sensor_stop_pin, INPUT_PULLUP);
attachInterrupt(1, sensor_stop, FALLING); //sensore induttivo collegato al pin 2
pinMode(motorPin,OUTPUT);// set the digital pin as output
ritardo = 3500;// pauses for microseconds us
ritardo_1 = 5000;// pauses for milliseconds ms
Serial.begin(9600);
}
void loop()
{
// see if switch is open or closed
switchState = digitalRead (switchPin);
// has it changed since last time?
if (switchState != oldSwitchState)
{
// debounce
if (millis () - switchPressTime >= debounceTime)
{
switchPressTime = millis (); // when we closed the switch
oldSwitchState = switchState; // remember for next time
if (switchState == LOW)
{
Serial.println ("Switch closed.");
digitalWrite(led_pin, HIGH);
} // end if switchState is LOW
else
{
Serial.println ("Switch opened.");
digitalWrite(led_pin, LOW);
} // end if switchState is HIGH
} // end if debounce time up
} // end of state change
if(k == 0)
{
k = 1;
delay(ritardo_1);
}
/*
//sezione motore
while(k == 1 && switchState == LOW)
{
digitalWrite(motorPin, LOW); // sets the pin on
delayMicroseconds(ritardo);// pauses for microseconds
digitalWrite(motorPin, HIGH); // sets the pin off
delayMicroseconds(ritardo);// pauses for microseconds
switchState = digitalRead(switchPin);
// Serial.println('a');
}
*/
motore();
}//fine loop
void sensor_stop()
{
k = 0;
}
void motore()
{
if(k == 1 && switchState == LOW)
{
digitalWrite(motorPin, LOW); // sets the pin on
delayMicroseconds(ritardo);// pauses for microseconds
digitalWrite(motorPin, HIGH); // sets the pin off
delayMicroseconds(ritardo);// pauses for microseconds
}
}
ciao
ho risolto scrivendo la funzione sotto interrupt in questo modo:
void sensor_stop()
{
if(digitalRead(sensor_stop_pin) == LOW)
{
k = 0;
}
else
{
k = 1;
}
}
qualcuno mi può spiegare come mai con un segnale che va da LOW ad HIGH del sensore, talvolta l'interrupt richiama ancora la funzione associata, i segnali controllati con oscilloscopio sono puliti.