Forum: Mikrocontroller und Digitale Elektronik DC Motor über Mikrocontroller schalten


von Lukas M. (cruxxx)


Angehängte Dateien:

Lesenswert?

Hallo,

bin absoluter Anfänger wenn es um Elektronik geht, deshalb brauch ich 
eure Hilfe.
Ich will ein digitales Signal nutzen um einen DC Motor ( 
http://m.conrad.de/ce/de/product/222366/GETRIEBEMOTOR-1481-45-15V-540ER-MOTOR?ref=searchDetail 
) mit einer gewissen Anschaltverzögerung für eine Zeit t einzuschalten 
danach soll der Vorgang wieder starten wenn wieder ein Eingangssignal 
vorliegt. Der Motor soll zwischen 4,5 und 12 V bei Handregler 
einstellbar sein. Ich habe eine Prinzipskizze angehängt die alles 
wichtige enthält.
Ich bräuchte Hilfe bei der Auswahl des Mikrocontrollers, des 
Transistors, der Schalter, des Widerstander und dem Regler. Bzw erstmal 
einen abgesegneten Schaltplan . Also im Prinzip alles XD.

Vielen Dank im Voraus!

: Verschoben durch Moderator
von Tobias P. (hubertus)


Lesenswert?

Falk Brunner (oder ein anderer) wird sich über dein 2MB Bild freuen.
Bin mal gespannt wie lange es dauert bis einer was sagt :-)

PS: warum im Offtopic?

von Christian B. (luckyfu)


Lesenswert?

Prinzipiell ist das Bild nicht nur riesig, auch noch auf dem Kopf!

Aber normalerweise kann man es so machen, den Motor einschalten über 
einen Transistor und die Regelung / das Polwenden über separate Bauteile 
wie Poti und Relais.
Aber man kann auch das Poti an den Controller hängen, mit dem 
Bordeigenen ADC den Wert auslesen und dann mittels PWM den Motor in 
seiner Drehzahl variieren. Das hat auch den Charme, daß du erstens kein 
großes Drahtpoti mit entsprechend mehreren Watt Leistung benötigst 
(Klobig und teuer) und außerdem hat der Motor mehr Drehmoment, da er 
immer mit der Maximalen Spannung bestromt wird.
Wenn das funktioniert kannst du die Ansteuerung um ein Signal erweitern 
und einen Motortreiber IC hinten dran hängen, welcher eine H-Brücke 
beinhaltet. Dieser sorgt dann dafür, daß du auch umpolen kannst, ganz 
ohne Relais.

von Lukas M. (cruxxx)


Lesenswert?

Danke luckyfu!

Wenn ich mit PWM den Motor ansteuere wie würde das auf dem Schaltplan 
aussehen? Welcher Mikrocontroller brauche ich ? Ich brauche dann ja nur 
2 Eingänge und 2 Ausgänge.

von Christian B. (luckyfu)


Lesenswert?

Ich habe sowas ähnliches mit einem ATtiny25 gemacht.
Allerdings geht es dabei eher darum einen Peltiertreiber mit passender 
Ansteuerung zu versehen. Das Ist also nur bedingt nutzbar. (Da hier eine 
einfache Regelschleife drin ist, welche du so nicht benötigst, auch 
frage ich 2 Ströme ab und regle dann entsprechend anhand der Differenz. 
Aber vielleicht kannst du ja doch etwas daraus nutzen. (Die PLL wirst du 
nicht brauchen. Ich hab hier aber eine 500kHz PWM, damit die Spulen nach 
dem Treiber möglichst klein sind.)

Prinzipiell kannst du einfach einen OCxA oder OCxB Ausgang nutzen. Diese 
hängen direkt an den Timern, wenn sie entsprechend konfiguriert sind) 
Dort dann einen Mosfet dran, welcher Logiclevel kompatibel ist und den 
Strom schalten kann oder eben gleich einen Motortreiber. In meinem Fall 
ist es ein DRV8412, aber der ist für deine Belange sicherlich vollkommen 
überdimensioniert.

Programm dazu:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "mydefs.h"
4
#include "main.h"
5
6
void init(void)
7
{
8
  PLLCSR = 1<<PLLE;          //PLL einschalten
9
  while(!(PLLCSR & (1<< PLOCK)));    // warten bis PLOCK ==1
10
  PLLCSR |= 1<<PCKE;          // pll als timer1 source  
11
  
12
  CLKPR = 0x80;
13
  CLKPR &= ~((1 << CLKPCE) | (1 << CLKPS1) | (1 << CLKPS0)); 
14
  
15
  DDRB = 0x12;    //beide PWM Kanäle als Ausgang einstellen
16
  
17
  //Timer 1 (500kHz PWM)
18
  OCR1C = 127;
19
  PLLCSR = 1<<PLLE;          //PLL einschalten
20
  while(!(PLLCSR & (1<< PLOCK)));    // warten bis PLOCK stabil
21
  PLLCSR |= 1<<PCKE;          // pll als timer1 source
22
  TCCR1 = (1 << CTC1) | (1 << CS10);
23
  
24
  ADCSRA |= (1 << ADEN) | (1 << ADPS2);
25
}
26
27
char Reloadwertberechnung(uint16_t I_Soll_calc, uint16_t I_Ist_calc, char Reloadwert_calc)
28
{  
29
  if(I_Soll_calc > I_Ist_calc)  
30
  {
31
    Reloadwert_calc ++;
32
  }
33
  else   
34
  {
35
    Reloadwert_calc --;
36
  }
37
  
38
  if(Reloadwert_calc > 122)
39
  {
40
    Reloadwert_calc = 122;
41
  }
42
  else if(Reloadwert_calc < 5)
43
  {
44
    Reloadwert_calc = 5;
45
  }  
46
47
  return Reloadwert_calc;
48
}
49
50
void Start_PWM(char Reloadwert_set)
51
{
52
  static uint8_t Cooling_tmp = 2;  //Kann nur bei erstem Start sein, danach pendelt der Wert zwischen 0 und 1, je nach Pin - Wert
53
    
54
  if(COOLING != Cooling_tmp)
55
  {
56
    if(COOLING == ON)
57
    {
58
      GTCCR &= ~((1 << PWM1B) | (1 << COM1B1) | (1 << COM1B0));
59
      PWM_HEIZEN = OFF;
60
      TCCR1 |= (1 << PWM1A) | (1 << COM1A1);
61
      Cooling_tmp = COOLING;
62
    }
63
    else
64
    {
65
      TCCR1 &= ~((1 << PWM1A) | (1 << COM1A1) | (1 << COM1A0));
66
      PWM_KUEHLEN = OFF;
67
      GTCCR |= (1 << PWM1B) | (1 << COM1B1);
68
      Cooling_tmp = COOLING;  
69
    }
70
  }
71
  OCR1A = Reloadwert_set;
72
  OCR1B = Reloadwert_set;
73
}
74
75
int ADC_Messung(uint8_t Kanal)
76
{
77
  uint8_t i;
78
  uint16_t Messwert;
79
  uint16_t Mittelwert = 0;
80
  
81
  ADMUX &= ~((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3));  
82
  ADMUX |= Kanal;  
83
  ADCSRA |= (1 << ADIF);
84
    
85
  for(i = 0; i < ADC_Messungen; i++)
86
  {
87
    ADCSRA |= (1 << ADSC);
88
    while(!(ADCSRA & (1 << ADIF)));  
89
    ADCSRA |= (1 << ADIF);
90
    Mittelwert += ADC;
91
  }
92
  ADCSRA &= ~(1 << ADSC);
93
  
94
  Messwert = Mittelwert / ADC_Messungen;
95
  Mittelwert = 0;
96
  
97
  return Messwert;
98
}
99
100
101
int main(void)
102
{
103
    uint8_t Reloadwert = 5;    
104
  uint16_t I_Soll, I_Ist;
105
  init();
106
  
107
  while(1)
108
    {
109
    I_Soll = ADC_Messung(1);                      //Sollwert Messung
110
    I_Ist =  ADC_Messung(3);                      //Istwert-Messung
111
    Reloadwert = Reloadwertberechnung(I_Soll, I_Ist, Reloadwert);    //Berechnung neuer Reloadwert für PWM
112
    Start_PWM(Reloadwert);                        //Start PWM und Umschalten Kühlen / Heizen
113
  }
114
}
die Header:
main.h:
1
#ifndef _main_h_
2
#define _main_h_
3
#include "mydefs.h"
4
5
#define COOLING SBIT( PINB, 0)   //Back
6
#define PWM_HEIZEN SBIT( PORTB, 4)
7
#define PWM_KUEHLEN SBIT( PORTB, 1)
8
9
#define ON 1
10
#define OFF 0
11
12
#define ADC_Messungen 50      //Anzahl der Messungen aus welchen der Mittelwert gebildet wird. Maximal möglich: 64
13
14
15
#endif
und mydefs.h: (Die hab ich mir für viele meiner Projekte adaptiert, 
stammt im Original aus einer LCD Lib)
1
/************************************************************************/
2
/*                                                                      */
3
/*                      Several helpful definitions                     */
4
/*                                                                      */
5
/*              Author: Peter Dannegger                                 */
6
/*                                                                      */
7
/************************************************************************/
8
#ifndef _mydefs_h_
9
#define _mydefs_h_
10
#include<avr/io.h>
11
12
13
// Access bits like variables
14
struct bits {
15
  uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
16
} __attribute__((__packed__));
17
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
18
#define  SBIT(x,y)       SBIT_(x,y)
19
20
21
// avoid push in main
22
int main( void )        __attribute__((OS_main));
23
24
25
// force access of interrupt variables
26
#define IVAR(x)         (*(volatile typeof(x)*)&(x))
27
28
29
// always inline function x
30
#define AIL(x)          static x __attribute__ ((always_inline)); static x
31
32
33
// NOP
34
#define nop()           __asm__ volatile("nop"::)
35
36
37
#endif

von Lukas M. (cruxxx)


Lesenswert?

Danke für die ausführliche Antwort. Aber leider kann ich damit Null 
anfangen, weil ich keinen Plan von der Materie habe :( . Gibt es eine 
Möglichkeit das ganze so einfach wie möglich ( für mich ) zu machen? Was 
hällst du von arduino uno?

von Christian B. (luckyfu)


Lesenswert?

damit hab ich noch nichts gemacht.
der ATTiny25 ist ein 8-beiniger Controller, den gibt es als SO-08 und 
bestimmt auch als DIL8. 2 Pins sind für die Betriebsspannung vorgesehen, 
dazwischen kommt ein 100nF Kondensator und gut ist.
Du hast nun 5+1 nutzbare Anschlüsse.
Einen Quarz o.ä. brauchst du nicht.
ich hab z.B. Pin 2 (PB3) und 7 (PB2) (ADC2 und 3) als Analogeingang 
genutzt und Pin 3 (PB4) und 6 (PB1) als Ausgang für den Treiber-IC.
Pin 5 (PB0) ist der Eingang zum Umschalten zwischen Kühlen und Heizen. 
(Also quasi das Umpolen).
Das sind die 5 Pins. den +1, das ist Pin 1 (PB5). das ist standardmäßig 
der !Reset. Ich habe den als Enable Pin genutzt. Heisst: Wenn die 
übergeordnete Elektronik den Treiber nicht benötigt ist der Controller 
im Reset. Wird er gebraucht bootet er und arbeitet dann normal.

Dann brauchst du noch einen 6-poligen Programmierstecker und ein 
passendes Programmiergerät, AVRISP MK2 z.B.

im Prinzip sehr einfach.

Du müsstest jetzt nur das Beispielprogramm von mir nehmen, die 
Analogwertmessung auf einen Kanal beschränken und deine Pausen mittels
1
delay_ms(xxx);
 einbauen. Dazu dann noch die avr/delay.h einladen und fertig.

Alles in allem kein so großes Ding. Auch als Anfänger nicht. Man muss 
sich nur trauen, geholfen wird dir hier immer, solange du 
Eigeninitiative zeigst. Wenn du allerdings der Meinung bist hier 
erstellt dir jemand den Schaltplan für ein Arduino inklussive passendem 
Programm bezweifle ich ehrlichgesagt, daß du Hilfe bekommst.
Da ich das mit so ziemlich dem kleinsten Controller gemacht habe den 
Atmel anbietet heisst das für dich: Du kannst jeden Controller dazu 
verwenden der mindestens 1 ADC und mindestens einen Timer hat.
Je nachdem, woher dein Startsignal kommt musst du es ggf. noch 
entprellen. Dazu findest du hier im Forum auch unzählige Threads. Da 
kannst du dir das passende heraussuchen.

von Michael .. (thing)


Lesenswert?

Lukas M. schrieb:
> Hallo,
>
> bin absoluter Anfänger wenn es um Elektronik geht, deshalb brauch ich
> eure Hilfe.
> Ich will ein digitales Signal nutzen um einen DC Motor (
> 
http://m.conrad.de/ce/de/product/222366/GETRIEBEMOTOR-1481-45-15V-540ER-MOTOR?ref=searchDetail
> ) mit einer gewissen Anschaltverzögerung für eine Zeit t einzuschalten
> danach soll der Vorgang wieder starten wenn wieder ein Eingangssignal
> vorliegt. Der Motor soll zwischen 4,5 und 12 V bei Handregler
> einstellbar sein. Ich habe eine Prinzipskizze angehängt die alles
> wichtige enthält.
> Ich bräuchte Hilfe bei der Auswahl des Mikrocontrollers, des
> Transistors, der Schalter, des Widerstander und dem Regler. Bzw erstmal
> einen abgesegneten Schaltplan . Also im Prinzip alles XD.

Für so was brauchst du keinen Mikrocontroller. Ein getriggerter 555
kann das auch locker packen. Damit würde ich mal anfangen. Später
kann man auch mal was verbessern und kann auf der Erfahrung aufbauen.
So übernimmst du dich nur. Wenn das einstellen einer Skizze dich schon
so überfordert, dann so ein mutiges Projekt mit µC ganz sicher.

von Lukas M. (cruxxx)


Lesenswert?

Michael ... schrieb:
> Wenn das einstellen einer Skizze dich schon
> so überfordert

Hast du ein Problem mit meiner Zeichnung?

von c.m. (Gast)


Lesenswert?

Lukas M. schrieb:
> Michael ... schrieb:
>> Wenn das einstellen einer Skizze dich schon
>> so überfordert
>
> Hast du ein Problem mit meiner Zeichnung?

ich sags mal so: wenn du das auch aufm kopp stehend gemalt hast… klasse!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.