Montag, 8. Juni 2015

Der kleine Laserplotter/-Cutter


Wie mein kleiner Laser-Plotter entstanden ist

Das Thema Laserplotter scheint im Internet und unter den E-Bastlern sehr verbreitet zu sein. Was mich aber nicht wunder, da es mich auch schnell gepackt hat und ich dem Fieber verfallen bin.

Also machte ich mich als erstes auf die Suche nach Informationen über Laser und über Schrittmotoren.
Was nicht ganz einfach war. Es gibt zwar viel im Netz, aber entweder ist es für Menschen die sich schon ausreichend mit der Technik auskennen geschrieben, oder mit nur sehr wenigen Informationen zu den Details.


Was ich hier versuchen möchte ist viele nützliche Informationen zusammen zu tragen und zu verlinken.





Der ARDUINO mit dem AFmotor Shield (L293D), 2 Stepper und ein Servo läuft ganz gut mit der Firmeware GcodeCNCdemo und zum senden der Daten (GCODE) teste ich gerade GcodeSender, auch von MarginallyClever.





Ausschneiden aus Kunststoff 



Da es immer noch Probleme mit der Einstellung von Stepps pro Millimeter gibt, muss eine neue Steuerung her.

Jetzt mit einem easyDriver Set und der GRBL Software. 










Für die nächste Ausbaustufe habe ich schon mal Material bestellt bei: www.alu-Profil-Technik.de
Superservice und gute Preise.



















Sonntag, 17. Mai 2015

Messen mit dem Ultraschall Modul HC-SR04 mit Ausgabe am PC oder auf LCD





Informationen zum HC-SR04 (Robosoftsystem)

************************************************************************************
Start Quellcode
************************************************************************************
// Prozesortaktfrequent festlegen
#define F_CPU 16000000UL



// Baudrate
#define BAUD 19200UL

// Baudratenberechnung
#define UBRR_VAL ((F_CPU+BAUD*8) / (BAUD*16)-1)

// CR ist Zeilenumbruch
#define CR 0x0D


// Benötigte Bibliotheken hinzufügen
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>




// Variablen deklarieren
uint16_t rising, falling;     // Zum speichern der Timerwerte bei steigender und fallender Flanke
int counts;                         // Die Differenz der beiden Timerwerte (Signallänge in TimerTakten)
float dist;                          // Der berechnete Abstand in cm mit bis zu 6 Kommastellen
uint16_t us_per_count;    // Die Länge eines TimerTaktes in us



// ********************************************************************************************************************************************
// ****************************************************** Serielle Übertragung ****************************************************************
// UART-Init ATmega328P

void uart_init(void)
{
    // Baudrate einstellen
    UBRR0H = (unsigned char)(UBRR_VAL>>8);
    UBRR0L = (unsigned char)UBRR_VAL;
   
    // Receiver und Transmitter einschalten
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
   
    // Frame Format: Asynchron 8N1
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}



// Charakter schreiben (Ein Zeichen senden als ASCII)
void uart_putChar(unsigned char c)
{
    // Warten bis Sendepuffer leer ist
    while (!(UCSR0A & (1<<UDRE0)));
   
    // Daten in den Puffer schreiben und senden
    UDR0 = c;
}



// String senden (Einen Zeichenfolge in einzelne Zeichen zerlegen und an uart_putChar zum senden übergeben)
void uart_putStr(unsigned char *s)
{
    while (*s)
    {  

        // so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)"
        uart_putChar(*s);
        s++;
    }
}
// ********************************************************************************************************************************************





// ********************************************************************************************************************************************
// ************************************************* ISP **************************************************************************************

// Int. wenn die sich verändernde Flanke (von "1 nach 0 - fallende" oder von "0 nach 1 - steigende") erkannt wird. (An PIN PB0 (ARDUINO PIN 8))

ISR(TIMER1_CAPT_vect)
{
    if (TCCR1B & (1<<ICES1))     // (Wenn das Bit ICES1 im register TCCR1B = 1 ist, also einen steigende Flanke erkennt)
    {
        TCCR1B &= ~(1<<ICES1);     // (Erkennung umschalten auf fallende Flanke (Bit ICES1 im register TCCR1B = 0))
        rising = ICR1;                           // (Den beim auslösen des Int. im Register ICR1 gespeicherten Timer/Counter Wert in die Variable "rising" speichern)

    }
    else // (Wenn das Bit ICES1 im register TCCR1B = 0 ist, also einen fallende Flanke erkennt)
    {
        TCCR1B |= (1<<ICES1);     // (Erkennung umschalten auf steigende Flanke (Bit ICES1 im register TCCR1B = 1))
        falling = ICR1;                      // (Den beim auslösen des Int. im Register ICR1 gespeicherten Timer/Counter Wert in die Variable "falling" speichern)
        counts = falling - rising;        // die Differenz zwischen tEnd und tStart berechnen (z.B.: Steigende Flanke erkannt bei tStart=120, fallenden Flanke erkannt bei tEnd=670 - 670-120=tPuls=550)

        dist = (float)us_per_count * counts * 10 / 580;     // (Laufzeit Schall in Weg "cm" umrechnen)
    }
}



// Is triggered on timer match of OCR1A (Int. wenn der Vergleichswert in OCR1A erreicht ist)
ISR(TIMER1_COMPA_vect)
{
    // Generate a 12us pulse to trigger the HR-SR04
    PORTB ^= (1<<PIN2);
    _delay_us(12);
    PORTB ^= (1<<PIN2);
}
// ********************************************************************************************************************************************


int main(void)
{
    // Uart Init
    uart_init();
   
    unsigned char str[10];
   
    DDRB |= (1<<PIN2);      // PORTB PIN 2 as output
    DDRB |= (1<<PIN5);      // PORTB PIN 5 as output
   
   
   
    // ********************************************************************************************************************************************
    // *************************************************************** TIMER1 INIT ****************************************************************

    TCCR1B |= (1<<ICNC1) | (1<<CS10) | (1<<CS11) | (1<<WGM12);      //ICNC1:Rauschunterdrückung, CS10 and CS11: Prescale (Teiler) auf 64, WGM12: CTC-Modus auswählen
    TIMSK1 |= (1<<ICIE1) | (1<<OCIE1A);      // Int. auslösen bei: Erreichen von TOP, bei steigender bzw. fallender Flanke
    TCCR1B |= (1<<ICES1);      // Int. auslösen bei steigender Flanke
   
    // TOP berechnen (70ms Laufzeit für einene Cyclus): 16MHz/64 = 250000count/sek = 250000/1000 = 25000count/us / 100 * 70 = 17500 count/70ms

    OCR1A = 17500;



      
    // CPU-Takt / Prescale = Takte/Sek. 1Sek / Takt/Sek = 4 ( t = 4us/Takt)
    us_per_count = 4;

    sei();     //Interrupt global aktivieren



    // Endlosschleife
    while (1)
    {
        if (dist < 300)     // Wenn die Distanz innerhalb des Messbereiches (max. 300cm) liegt, ...
        {
            uart_putStr(dtostrf(dist, 1, 2, str));     // ... dann Ausgabe der Distanz mit 2 Stellen hinter dem Komma per Seriell
            uart_putStr(" cm");      // schreibe hinter dem Wert ein "cm"
            uart_putStr("\r");     // gehe zurück zum Anfang der Zeile
        }
        else     // Wenn nicht, ...
        {
            uart_putStr("ERROR");     // ... schreibe "ERROR" in dei Ausgabe
            uart_putStr("\r");    
// gehe zurück zum Anfang der Zeile 
        }
       
       
        _delay_ms(250);
    }
}


**********************************************************************************
Ende Quellcode
**********************************************************************************



Diese Seiten habne mir geholfen das Projekt umzusetzen:

Attiny2313 Ultrasonic distance (HR-SR04) example
ATmega168/328-Arduino Pin Mapping
CONVERTWORLD.COM - Umrechnen von Einheiten ganz einfach

Vielen Dank!

Samstag, 16. Mai 2015

Programmieren von AVR ATmega328P (ATmega 8Bit Prozessoren) in C und C++

Hallo zusammen,

Ich möchte in diesem Block meine persönlichen Erfahrungen in der Programmierung von Mikrocontrollern mit Euch teilen.

Ich werde diesen Blog Stück für Stück aufbauen und mit meinem Quellcode so wie mit interessanten Link versehen.

Wenn Ihr Ideen zu Projekten habt, lass mich das bitte wissen. Wenn Zeit und Muße stimmen, werde ich mich gerne daran beteiligen.

Geplante Versuche:
  • Serielle Ausgabe UART
  • ADC - Einen analogen Eingang nutzen
  • Thermesensor
  • PWM
  • Ein Servo steuern
  • LCD - ansteuern und benutzen
  • ICP - Zeitmessung und Signalauswertung
  • Ultraschall Modul HC-SR04
  • Photodiode
  • Funkmodul 433MHz