PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Stoppuhr mit laserlichtschranke



Koertis
12.04.2012, 14:53
Hallo liebe Forumsmitglieder,


ich habe ein Problem: Ich habe eine Stoppuhr mit Laserlichtschranke gebaut. Die 5m entfernte Laserlichtschranke funktioniert problemlos. Ich habe aber auch 2 Taster die auch 5m entfernt sind angebracht, diese lösen einen Interrupt aus und sollten die Stoppuhr starten/stoppen bzw. rücksetzen. Leider funktionieren diese beiden nur sporadisch. Laut Oszi kommen die Signale am µC an, also kann ich mir das nicht erklären. Für Ratschläge wäre ich sehr dankbar.



#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include <avr/interrupt.h>

//Konstanten
#define timer0_ovf 16000

//--Siebensegmentanzeigen
#define ZERO 0x3F
#define ONE 0x06
#define TWO 0x5B
#define THREE 0x4F
#define FOUR 0x66
#define FIFE 0x6D
#define SIX 0x7D
#define SEVEN 0x07
#define EIGHT 0x7F
#define NINE 0x6F


volatile uint16_t debounce = 0;
volatile uint16_t wait_ms = 0;
volatile uint8_t time = 0;
volatile uint8_t A[10]={0,0,0,0,0,0,0,0,0,0};//{0,1,2,3,4,5,6,7,8,9};//
uint8_t Symbols[10] = {ZERO,ONE,TWO,THREE,FOUR,FIFE,SIX,SEVEN,EIGHT,NINE };
volatile uint8_t Enable = 0;
volatile uint8_t Int = 0;
volatile uint8_t Reset = 0;
volatile uint8_t Lock = 0;

void WAIT_MS(uint16_t i){
wait_ms = i;
while(wait_ms);
}


void init_all(void){
DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0x00;

PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;

sei();

GICR |= (1<<INT0)|(1<<INT1);
MCUCR |= (1<<ISC01)|(1<<ISC11)|(1<<ISC10);

//--Timer0 einstellungen
TCCR1B |= (1<<CS10)|(1<<WGM12);

TIMSK |= (1<<OCIE1A);
OCR1A = timer0_ovf;

}




void TIME(void) {
A[0]++;
if(A[0] == 10) {
A[0]= 0;
A[1]++;
if(A[1] == 10){
A[1]=0;
A[2]++;
if(A[2] == 10){
A[2] = 0;
A[3]++;
if(A[3] ==10){
A[3] = 0;
A[4]++;
if(A[4] == 6){
A[4] = 0;
A[5]++;
if(A[5] == 10){
A[5] = 0;
A[6]++;
if(A[6]==6){
A[6]=0;
A[7]++;
if(A[7]==10){
A[7]=0;
A[8]++;
if(A[8]==10)
A[8]=0;
}
}
}
}
}
}
}
}
}




void OUTPUT(void){
for(uint8_t i = 0; i<5;i++){
PORTC = 0b10000>>i;
if( i == 3)
PORTA = Symbols[A[i]]|0x80;
else
PORTA = Symbols[A[i]];
if( i == 1|| i ==3)
PORTB = Symbols[A[4+i]]|0x80;
else
PORTB = Symbols[A[4+i]];
WAIT_MS(2);
PORTA = 0;
PORTB = 0;
WAIT_MS(1);
}
}


int main(void){
init_all();
while(1){
OUTPUT(); // 7-Segmentausgabe
if(Int && !Lock){
if(Enable)
Enable = 0; // Zeit wird nicht mehr inkrementiert
else
Enable = 1; // Zeit wird inkrementiert
Lock = 1;
debounce = 500;
Int = 0;
}
if(Reset){
for(uint8_t t = 0; t<=10; t++)
A[t] = 0;
Enable = 0;
Reset = 0;
Int = 0;
debounce = 0;
}
if(Lock && !debounce){ // Das am ende der Prellzeit der Interrupt zurückgesetzt wird.
Int= 0;
Lock = 0;
}
}
return 0;
}

ISR(TIMER1_COMPA_vect){
if(debounce)
debounce--; // Prellzeit
if(wait_ms)
wait_ms--; // warteroutine
if(Enable)
TIME(); // inkrementieren der Zeit
}

/*ISR (TIMER2_OVF_vect){
TIME();
}*/

ISR(INT0_vect) {
if(!(PIND & (1<<PD0))){ // Laserlichtschranke
if(!Int)
Int = 1;
}
}

// Interrupt für Taster
ISR(INT1_vect){
if(!(PIND & (1<<PD5))){// Start/Stop Taster
if(!Int)
Int = 1;
}
if(!(PIND & (1<<PD4))){ // Rücksetztaste
//Enable = 0;
Reset =1;
}
}


Ich hoffe der Code ist nicht zu chaotisch.
Ich habe nun alles probiert schaffe es jedoch nicht ein Bild oder Anhang hinzu zu fügen.

vielen Dank,
lg Koertis

HannoHupmann
13.04.2012, 13:57
https://www.roboternetz.de/community/threads/56875-Gut-und-g%C3%BCnstig-Lichtschranke-f%C3%BCr-Distanz-von-2m/page4

Vielleicht hast du das selbe Problem wie ich? Mein Code ist aber anders ich schick ihn dir gerne mal zu bzw. kann ihn posten. Ich hab ihn beim µController.net geklaut.

Koertis
13.04.2012, 17:58
Ja bitte, ich denke das es ein Programmfehler ist, denn laut Oszi liegen am µC bei low 100mV und bei high gute 5V an, wenn die Taster gedrückt werden. Anfangs dachte ich dass ich vieleicht die Pull-Up Widerstände zu hoch dimensioniert haben, aber laut Oszi kommt das Signal an. Anders: wenn ich den Interrupt direkt ausgeben lasse, wird dieser oft nicht registriert. Nun weiß ich nicht ob das ein HW-oder SW Problem ist...

PICture
13.04.2012, 19:22
Hallo!


Nun weiß ich nicht ob das ein HW-oder SW Problem ist...

Das sollte bei 5 cm (anstatt 5 m) langen Leitungen zum Taster, ohne Oszi, feststellbar sein. ;)

Koertis
14.04.2012, 13:26
Wenn ich die kontakte nach 3cm auf Masse ziehe funktioniert alles Problemlos. Also liegt der Fehler doch in der HW. Hat jemand eine Idee was fehlen könnte? ich habe einen Pull up von 10k ohm. Wie weit sollte ich diesen verringern? sofern das das problem ist?

HannoHupmann
14.04.2012, 13:45
Ich verwende folgenden Code und nen mega32 dafür:



#include <stdlib.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/delay.h>
#include "digits.h"

#define SYSCLK 7372800UL // timer clock 8Mhz
// |= High
// &= ~ low

int x = 0; // 1/100sec
int y = 0; // 1/10 sec
int z = 0; // 1 sec
int stopp = 0;
int running;
int counter;
double sec = 0;

ISR(INT0_vect){
// Starte Messung
TCCR0 = 0x01;
running = 1;
}

ISR(INT1_vect){
// Stopp Messung
TCCR0 = 0x00;
running = 0;
stopp = 1;
}


ISR(TIMER0_OVF_vect)
{
if (!(PINA & (1<<PINA2)))
{
TCCR0 = 0x01;
running = 1;
}

if (running == 1)
counter++;
else
counter = 0;

//if (counter > 625) //7,3728MHz ohne Prescaler: (7372800/256)/288=100 --> 1/100sek Auflösung
if (counter > 287)
{
x++;
counter = 0;
sec++;
}

if (x > 9) //Zählen der einzelnen Stellen:
{
x=0;
y++;

}
if (y > 9)
{
y=0;
z++;
}
if (z > 9)
{
TCCR0 = 0x00;
}

}




void IRQ_init(void){
cli(); // Interrupts ein sei()

GICR |= (0<<INT0); // externer INT Disable
GICR |= (0<<INT1);

MCUCR |= (1<<ISC10); // Einstellen des Auslösers = Seite 67 Datasheet mega 32
MCUCR |= (1<<ISC11);

MCUCR |= (1<<ISC00);
MCUCR |= (1<<ISC01);

GICR |= (1<<INT0); // extern INT Enable
GICR |= (1<<INT1);

TCNT0 = 0x00; //Timer0 mit 0 initialisieren (00000000)
TIMSK = 0x01;

sei(); // Interrupts aus cli()

}







int main(void)
{
// Pin als Eingang mit Pullup
DDRA = (0 << DDA2); // Programm
DDRD = (0 << DDD2) | (0 << DDD3); // Interrupts A und B
PORTA |= (1<<PA2);
PORTD |= (1<<DD2) | (1<<DD3);

//Timer/Counter Control Register 0
//CS02, CS01 und CS00: Prescale auf 256
TCCR0 = (1<<CS02) | (0<<CS01) | (0<<CS00);


// Digit 1: B0, B1, B2, B3
DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3);
// Digit 2: C4, C5, C6, C7
// Digit 3: C0, C1, C2, C3
DDRC = (1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1 << DDC4) | (1 << DDC5) | (1 << DDC6) | (1 << DDC7);
DDRD = (1 << DDD5);
DDRA = (1 << DDA0);

IRQ_init();
int a = 0, b = 0, c = 0;
short value = 0;
running = 0;

PORTA &= ~ (1<<PA0);

while(1)
{
digit1(z);
digit2(y);
digit3(x);

while (stopp == 1){
digit1(z);
digit2(y);
digit3(x);
_delay_ms(50000);

value = (1.395/(sec/100)) *3.6*10; //1,394 Länge zwischen S1 und S2 mit 10 für Anzeige 01,0 m/s)

a = value % 10;
value = value / 10;

b = value % 10;
value = value / 10;

c = value % 10;

digit1(c);
digit2(b);
digit3(a);
_delay_ms(50000);
}

}
}



Ansonsten hilft es das Signal direkt am Sensor umzuwandeln in High-Low und dann so zum µC zu übertragen. Man sollte generell die Signal-Wandlung immer so nah wie möglich am Sensor machen und nicht den Sensorwert über die Leitung schicken.

Koertis
14.04.2012, 14:37
Danke für den Code, aber ich denke es ist ein HW Problem, denn wenn ich auf der Platine das Signal auf GND ziehe schaltet die Uhr problemlos. Nur wenn ich meine 5m Kabel dranhänge schaltet die Uhr sporadisch. Ich habe auch eine entstörschaltung probiert, jedoch ohne erfolg.

PICture
14.04.2012, 16:57
Mann könnte mit geschirmten Kabel für Taster probieren. Notfalls, wegen eigener Kabelkapazität und Induktivität des Kabels, wäre Entprellung (Schmitt-Trigger Eingang ?) der Signale nötig. ;)

Koertis
16.04.2012, 08:06
Jetzt habe ich die Ursache bekämpft. Ich habe bei den Int0 & Int1 statt der steigenden Flanke die fallende Flanke genommen also nur: MCUCR |= (1<<ISC01)|(1<<ISC11); Und nun geht es. Was das jetzt für ein Unterschied macht verstehe ich nicht. Kann mir das jemand bitte erklären?
Geschirmte Kabel hatte ich schon im vornherein eingebaut.

Danke lg Koertis

PICture
16.04.2012, 14:16
Hallo!

Ich kann das nur damit erklären, dass ein Taster beim Loslassen meistens nicht prellt, was ich beim Experimentieren mit µC bemerkt habe: https://www.roboternetz.de/community/threads/26098-Tips-Tricks?p=337334&viewfull=1#post337334 . ;)