Skocz do zawartości

Moje własne bramki laserowe


Chumanista

Pomocna odpowiedź

Od dłuższego czasu miałem zamiar zbudować urządzenie do automatycznego pomiaru czasu przejazdu dla moich robotów. Po zobaczeniu tematu aktualnego konkursu postanowiłem wreszcie zabrać się do roboty. Przy okazji odkryłem możliwość taniego zamawiania PCB w chinach z którego skorzystałem w tym projekcie.

Projekt

Cały projekt opiera się na częściach znalezionych w szufladzie:

  • 1. Atmega 8 z zewnętrznym kwarcem 16MHz
  • 2. LM339
  • 3. 2 potencjometry 1k - do ustalania kontrastu LCD oraz progu komparatora
  • 4. HC-05 - moduł bluetooth
  • 5. HD44780 - LCD 16x2 znaki
  • i trochę drobnicy.

Łączny koszt (z PCB) - ok. 40zł/szt.

Zasada działania jest prosta: fotorezystor wraz z rezystorem 1k tworzą dzielnik napięcia. W zależności od tego czy światło lasera pada na fotorezystor czy nie ma on rezystancję <200Ω lub >1kΩ. Następnie napięcie z dzielnika jest porównywane z progiem ustawionym na potencjometrze RV1 (2V).

ATmega odczytuje stan 4 pinów i na tej podstawie mierzy czas. Do tego każda zmiana jest wraz z timestampem wysyłana przez UART do modułu Bluetooth w celu połączenia z komputerem. Docelowo ma to służyć do zatrzymywania robota po przekroczeniu ostatniej bramki.

Niestety okazało się że źle przeczytałem pinout ATmegi, przez co musiałem poprawić podłączenie LCD przewodami.

Czujniki zostały tak podłączone testowo, w przyszłości zbuduję porządne bramki oraz wydrukuję obudowę do kontrolera.

Zostało mi 9 płytek, wrzucę je do Big Box of Parts.

Program

Do pomiaru czasu wykorzystałem przeportowaną z Arduino bibliotekę wiring.h (millis()) oraz bibliotekę do LCD Petera Fleury.

/*
* GccApplication1.c
*
* Created: 2015-08-22 11:13:14
*  Author: Chumanista
*/ 

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include "lcd.h"
#include "wiring.h"

#define USART_BAUDRATE 109000 //115200
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

inline void write999Padded(uint32_t toWrite){
lcd_putc('0' + toWrite/100);
lcd_putc('0' + (toWrite%100)/10);
lcd_putc('0' + toWrite%10);
}

inline void write999Spaced(uint32_t toWrite){
if(toWrite > 100){
	lcd_putc('0' + toWrite/100);
} else {
	lcd_putc(' ');
}
if(toWrite > 10){
lcd_putc('0' + (toWrite/10)%10);
} else {
lcd_putc(' ');
}
lcd_putc('0' + toWrite%10);
}

int main(void)
{
lcd_init(LCD_DISP_ON);
wiring_init();
lcd_clrscr();
PORTD |= _BV(PD4) | _BV(PD5) | _BV(PD6) | _BV(PD7); //pullup
uint32_t startms = 0;
uint8_t lastState = PIND >> 4;

uint32_t lasttime = 0;

lcd_puts("Previous:  0:000");
lcd_gotoxy(0,1);
lcd_puts("Current:   0:000");

UCSRB = (1 << RXEN) | (1 << TXEN);   // Turn on the transmission and reception circuitry
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register

   while(1)
   {
	uint32_t mB = millis();
	uint8_t state = PIND >> 4;
	if(state != lastState){
		while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
		UDR = state;
		_delay_us(100);			
		while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
		UDR = (uint8_t) (mB >> 24);
		_delay_us(100);
		while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
		UDR = (uint8_t) (mB >> 16);
		_delay_us(100);
		while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
		UDR = (uint8_t) (mB >> 8);
		_delay_us(100);
		while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
		UDR = (uint8_t) mB;

		if(state > lastState){
			lcd_gotoxy(9,0);
			write999Spaced(lasttime/1000);
			lcd_putc(':');
			write999Padded(lasttime%1000);
			lasttime = mB - startms;
			lcd_gotoxy(9,1);
			write999Spaced(lasttime/1000);
			lcd_putc(':');
			write999Padded(lasttime%1000);
			startms = mB;
		}
	}
	lastState = state;
   }
}

Pomiary wykazały dokładność lepszą niż 0,1s, zupełnie zadowalającą do moich potrzeb.

2.thumb.png.132f4fa44a21a6a033f4e7e2f4495037.png

1.thumb.jpg.0116a4881c7d832be9733f12c46bc65d.jpg

  • Lubię! 1
Link do komentarza
Share on other sites

Podoba Ci się ten projekt? Zostaw pozytywny komentarz i daj znać autorowi, że zbudował coś fajnego!

Masz uwagi? Napisz kulturalnie co warto zmienić. Doceń pracę autora nad konstrukcją oraz opisem.

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.