Forum: Mikrocontroller und Digitale Elektronik manuelle Steuerung für CNC-Fräse


von Axel L. (lemmi4711)


Angehängte Dateien:

Lesenswert?

Um meine Selbstbau-CNC-Fräse auch mal schnell manuell bedienen zu können 
habe ich mir eine kleine 4 Achsen Step/Dir - Handsteuerung mit einem 
Mega8515 gebaut. Ausgegeben wird es auf ein Parallelportkabel. Die 
Stromversorgung kommt via USB...

Die 12 Richtungstasten habe ich über eine 4x4 Tastaturmartix abgefragt.
Über einen Stufenschalter habe ich die Schrittweite pro Tastendruck 
definiert. Auch für längere Fahrten habe ich eine Drehschalterpostion 
als Dauertakt (solange Taste gedrückt..) auf Step realisiert.

Das gesamte Baumaterial habe ich aus meiner Kramkiste rausgesucht, daher 
ist alles einfach "quick & dirty" auf Lochrasterplatine realisiert...

Laut Oszi kommen die Signale genau so raus, wie sie sollen. Leider kann 
ich das Teil noch nicht an meiner Fräse testen, da die Motortreiber erst 
nächste Woche eingebaut werden können...

Ich denke, Schaltplan und Code könnten auch noch optimimierungsfähig 
sein; das habe ich nur mal schnell zusammengetrommelt.

LG, Axel.


Hier noch der Code...
1
/*
2
 * CNC_Handsteuerung.cpp
3
 * "quick and dirty"
4
 *
5
 * Created: 24.03.2013 17:02:14
6
 *  Author: Axel Lemke
7
*/
8
9
#define F_CPU      8000000UL
10
11
#define MATRIXPORT    PORTA                // Matrixtastatureinstellungen
12
#define MATRIXPIN    PINA
13
14
#define MATRIX_ZEILE1  PA7
15
#define MATRIX_ZEILE2  PA6
16
#define MATRIX_ZEILE3  PA5
17
#define MATRIX_ZEILE4  PA4
18
19
#define MATRIX_SPALTE1  PINA3
20
#define MATRIX_SPALTE2  PINA2
21
#define MATRIX_SPALTE3  PINA1
22
#define MATRIX_SPALTE4  PINA0
23
24
#define STUFE_PIN1    PINB                // Stufenschaltereinstellungen
25
#define STUFE_PIN2    PINC
26
#define STUFE1      PINB0
27
#define STUFE2      PINB1
28
#define STUFE3      PINB2
29
#define STUFE4      PINB3
30
#define STUFE5      PINB4
31
#define STUFE6      PINB5
32
#define STUFE7      PINB6
33
#define STUFE8      PINB7
34
#define STUFE9      PINC5
35
#define STUFE10      PINC6
36
#define STUFE11      PINC7
37
38
#define OVR_PIN      PINC                // Override - Taster
39
#define OVR        PINC2
40
41
#define LED_PORT    PORTC                // LED - Porteinstellungen
42
#define BLINK_LED    PC4
43
#define OVR_LED      PC3
44
45
#define PP_PORT1    PORTD                // Parallelporteinstellungen
46
#define PP_PORT2    PORTC
47
#define PP_PIN      PIND
48
#define ENABLE  PC1                      
49
#define STOP  PD2
50
#define  DIR_X  PD1
51
#define STEP_X  PD0
52
#define DIR_Y  PD4
53
#define STEP_Y  PD3
54
#define DIR_Z  PD6
55
#define STEP_Z  PD5
56
#define DIR_A  PD7
57
#define STEP_A  PC0
58
59
#define SD1    80                      // Stepdelay, schnell (~200µs / Schritt)
60
#define SD2    360                      // Stepdelay, langsam (~1200µs / Schritt)
61
62
#include <avr/io.h>
63
#include <avr/interrupt.h>
64
#include <util/delay.h>
65
66
volatile uint8_t taste;
67
volatile uint16_t step;
68
uint16_t geschwindigkeit;
69
70
ISR (INT0_vect)
71
{
72
  taste = 0;
73
  step = 0;
74
  while (!(PP_PIN & (1<<STOP)))              // Stopp-Tasterkontrolle und Endschalterkontrolle
75
  {
76
    if (!(OVR_PIN & ( 1<<OVR)))              // Override - Taster bricht Interruptroutine ab     (soll es jedenfalls...)
77
    {                          // Das soll im Falle des Erreichen eines Endschalters die Rückkehr in den erlaubten Bereich ermöglichen.
78
      return;                      // ACHTUNG!!!!!  ES GIBT DANN KEINE SICHERHEITSABFRAGE MEHR!!!
79
    }
80
    LED_PORT ^= (1<<BLINK_LED);
81
    LED_PORT |= (1<<OVR_LED);
82
    _delay_ms(500);
83
  }
84
  LED_PORT &= ~(1<<BLINK_LED);
85
}
86
87
void delay_ms(uint16_t count)
88
{
89
  while(count--)
90
  {
91
    _delay_ms(1);
92
  }
93
}
94
95
void delay_us(uint16_t count)
96
{
97
  while(count--)
98
  {
99
    _delay_us(1);
100
  }
101
}
102
103
int uC_Init ()                        // Systemeinstellungen am µC
104
{
105
  DDRA  = 0b11110000;
106
  PORTA = 0b11111111;
107
  DDRB  = 0b00000000;
108
  PORTB = 0b11111111;
109
  DDRC  = 0b00011111;
110
  PORTC = 0b11100111;
111
  DDRD  = 0b11111011;
112
  PORTD = 0b00000100;
113
  
114
  GICR  |= (1<<INT0);
115
  return (0);
116
}
117
118
int Matrix ()                        // Abfrage der 4x4 Matrixtastatur und Rückgabe eines Wertes in eine globale Variable
119
{
120
    uint8_t matrix;
121
    taste = 0;
122
    MATRIXPORT &= ~(1<<MATRIX_ZEILE1);
123
    _delay_ms(1);                    // warten, um parasitäre Kapazitäten abzubauen...
124
    if (!(MATRIXPIN & (1<<MATRIX_SPALTE1)))
125
    {
126
      if (STUFE_PIN2&(1<<STUFE11))
127
      {
128
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE1)))
129
        {;}
130
      }
131
      matrix = 1;
132
    }
133
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE2)))
134
    {
135
      if (STUFE_PIN2&(1<<STUFE11))
136
      {
137
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE2)))
138
        {;}
139
      }      
140
      matrix = 2;
141
    }
142
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE3)))
143
    {
144
      if (STUFE_PIN2&(1<<STUFE11))
145
      {
146
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE3)))
147
        {;}
148
      }      
149
      matrix = 3;
150
    }
151
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE4)))
152
    {
153
      if (STUFE_PIN2&(1<<STUFE11))
154
      {
155
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE4)))
156
        {;}
157
      }    
158
      matrix = 4;
159
    }
160
    MATRIXPORT |= (1<<MATRIX_ZEILE1);
161
162
    MATRIXPORT &= ~(1<<MATRIX_ZEILE2);
163
    _delay_ms(1);                    // warten, um parasitäre Kapazitäten abzubauen...
164
    if (!(MATRIXPIN & (1<<MATRIX_SPALTE1)))
165
    {
166
      if (STUFE_PIN2&(1<<STUFE11))
167
      {
168
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE1)))
169
      {;}
170
      }
171
      matrix = 5;
172
    }
173
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE2)))
174
    {
175
      if (STUFE_PIN2&(1<<STUFE11))
176
      {
177
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE2)))
178
      {;}
179
      }
180
      matrix = 6;
181
    }
182
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE3)))
183
    {
184
      if (STUFE_PIN2&(1<<STUFE11))
185
      {
186
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE3)))
187
      {;}
188
      }
189
      matrix = 7;
190
    }
191
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE4)))
192
    {
193
      if (STUFE_PIN2&(1<<STUFE11))
194
      {
195
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE4)))
196
      {;}
197
      }
198
      matrix = 8;
199
    }
200
    MATRIXPORT |= (1<<MATRIX_ZEILE2);
201
202
    MATRIXPORT &= ~(1<<MATRIX_ZEILE3);
203
    _delay_ms(1);                    // warten, um parasitäre Kapazitäten abzubauen...
204
    if (!(MATRIXPIN & (1<<MATRIX_SPALTE1)))
205
    {
206
      if (STUFE_PIN2&(1<<STUFE11))
207
      {
208
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE1)))
209
      {;}
210
      }
211
      matrix = 9;
212
    }
213
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE2)))
214
    {
215
      if (STUFE_PIN2&(1<<STUFE11))
216
      {
217
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE2)))
218
      {;}
219
      }
220
      matrix = 10;
221
    }
222
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE3)))
223
    {
224
      if (STUFE_PIN2&(1<<STUFE11))
225
      {
226
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE3)))
227
      {;}
228
      }
229
      matrix = 11;
230
    }
231
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE4)))
232
    {
233
      if (STUFE_PIN2&(1<<STUFE11))
234
      {
235
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE4)))
236
      {;}
237
      }
238
      matrix = 12;
239
    }
240
    MATRIXPORT |= (1<<MATRIX_ZEILE3);
241
242
    MATRIXPORT &= ~(1<<MATRIX_ZEILE4);
243
    _delay_ms(1);                    // warten, um parasitäre Kapazitäten abzubauen...
244
    if (!(MATRIXPIN & (1<<MATRIX_SPALTE1)))
245
    {
246
      if (STUFE_PIN2&(1<<STUFE11))
247
      {
248
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE1)))
249
      {;}
250
      }
251
      matrix = 13;
252
    }
253
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE2)))
254
    {
255
      if (STUFE_PIN2&(1<<STUFE11))
256
      {
257
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE2)))
258
      {;}
259
      }
260
      matrix = 14;
261
    }
262
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE3)))
263
    {
264
      if (STUFE_PIN2&(1<<STUFE11))
265
      {
266
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE3)))
267
      {;}
268
      }
269
      matrix = 15;
270
    }
271
    else if (!(MATRIXPIN & (1<<MATRIX_SPALTE4)))
272
    {
273
      if (STUFE_PIN2&(1<<STUFE11))
274
      {
275
        while(!(MATRIXPIN & (1<<MATRIX_SPALTE4)))
276
      {;}
277
      }
278
      matrix = 16;
279
    }
280
    MATRIXPORT |= (1<<MATRIX_ZEILE4);
281
    taste = matrix;
282
    
283
  return (0);
284
}
285
286
int Stufenschalter ()                    // Abfrage des Stufenschalters
287
{
288
  if (!(STUFE_PIN1&(STUFE1)))
289
  {
290
    step = 1;
291
    geschwindigkeit = SD2;
292
  }
293
  if (!(STUFE_PIN1&(STUFE2)))
294
  {
295
    step = 1;
296
    geschwindigkeit = SD1;
297
  }
298
  if (!(STUFE_PIN1&(1<<STUFE3)))
299
  {
300
    step = 10;
301
    geschwindigkeit = SD2;
302
  }
303
  if (!(STUFE_PIN1&(1<<STUFE4)))
304
  {
305
    step = 10;
306
    geschwindigkeit = SD1;
307
  }
308
  if (!(STUFE_PIN1&(1<<STUFE5)))
309
  {
310
    step = 100;
311
    geschwindigkeit = SD2;
312
  }
313
  if (!(STUFE_PIN1&(1<<STUFE6)))
314
  {
315
    step = 100;
316
    geschwindigkeit = SD1;
317
  }
318
  if (!(STUFE_PIN1&(1<<STUFE7)))
319
  {
320
    step = 1000;
321
    geschwindigkeit = SD2;
322
  }
323
  if (!(STUFE_PIN1&(1<<STUFE8)))
324
  {
325
    step = 1000;
326
    geschwindigkeit = SD1;
327
  }
328
  if (!(STUFE_PIN2&(1<<STUFE9)))
329
  {
330
    step = 10000;
331
    geschwindigkeit = SD2;
332
  }
333
  if (!(STUFE_PIN2&(1<<STUFE10)))
334
  {
335
    step = 10000;
336
    geschwindigkeit = SD1;
337
  }
338
  if (!(STUFE_PIN2&(1<<STUFE11)))
339
  {
340
    step = 1;
341
    geschwindigkeit = SD1;
342
  }
343
  return (0);
344
}
345
346
int Stepper ()                        // Ausführen der vorher eingestellten Werte und Ausgabe an den Parallelport
347
{
348
  uint16_t i=0;                      // Abfrage der Matrixtastaturwerte und auswerten via switch/case - Anweisung
349
  switch (taste)
350
  {    
351
    case 1:
352
    PP_PORT1 &= ~(1<<DIR_X);
353
    PP_PORT1 |= (1<<DIR_Y);
354
    _delay_us(1);
355
    PP_PORT2 &= ~(1<<ENABLE);
356
    _delay_us(1);
357
    while (i<step)
358
    {
359
      PP_PORT1 |= ((1<<STEP_X)|(1<<STEP_Y));
360
      delay_us(geschwindigkeit);
361
      PP_PORT1 &= ~((1<<STEP_X)|(1<<STEP_Y));
362
      delay_us(geschwindigkeit);
363
      i++;
364
    }
365
    PP_PORT2 |= (1<<ENABLE);
366
    break;
367
    
368
    case 2:
369
    PP_PORT1 |= (1<<DIR_Y);
370
    _delay_us(1);
371
    PP_PORT2 &= ~(1<<ENABLE);
372
    _delay_us(1);
373
    while (i<step)
374
    {
375
      PP_PORT1 |= (1<<STEP_Y);
376
      delay_us(geschwindigkeit);
377
      PP_PORT1 &= ~(1<<STEP_Y);
378
      delay_us(geschwindigkeit);
379
      i++;
380
    }
381
    PP_PORT2 |= (1<<ENABLE);
382
    break;
383
    
384
    case 3:
385
    PP_PORT1 |= (1<<DIR_X)|(1<<DIR_Y);
386
    _delay_us(1);
387
    PP_PORT2 &= ~(1<<ENABLE);
388
    _delay_us(1);
389
    while (i<step)
390
    {
391
      PP_PORT1 |= ((1<<STEP_X)|(1<<STEP_Y));
392
      delay_us(geschwindigkeit);
393
      PP_PORT1 &= ~((1<<STEP_X)|(1<<STEP_Y));
394
      delay_us(geschwindigkeit);
395
      i++;
396
    }
397
    PP_PORT2 |= (1<<ENABLE);
398
    break;
399
    
400
    case 4:
401
    PP_PORT1 &= ~(1<<DIR_Z);
402
    _delay_us(1);
403
    PP_PORT2 &= ~(1<<ENABLE);
404
    _delay_us(1);
405
    while (i<step)
406
    {
407
      PP_PORT1 |= (1<<STEP_Z);
408
      delay_us(geschwindigkeit);
409
      PP_PORT1 &= ~(1<<STEP_Z);
410
      delay_us(geschwindigkeit);
411
      i++;
412
    }
413
    PP_PORT2 |= (1<<ENABLE);
414
    _delay_us(10);
415
    break;
416
    
417
    case 5:
418
    PP_PORT1 &= ~(1<<DIR_X);
419
    _delay_us(1);
420
    PP_PORT2 &= ~(1<<ENABLE);
421
    _delay_us(1);
422
    while (i<step)
423
    {
424
      PP_PORT1 |= (1<<STEP_X);
425
      delay_us(geschwindigkeit);
426
      PP_PORT1 &= ~(1<<STEP_X);
427
      delay_us(geschwindigkeit);
428
      i++;
429
    }
430
    PP_PORT2 |= (1<<ENABLE);
431
    break;
432
    
433
    case 6:
434
    // unbenutzt
435
    break;
436
    
437
    case 7:
438
    PP_PORT1 |= (1<<DIR_X);
439
    _delay_us(1);
440
    PP_PORT2 &= ~(1<<ENABLE);
441
    _delay_us(1);
442
    while (i<step)
443
    {
444
      PP_PORT1 |= (1<<STEP_X);
445
      delay_us(geschwindigkeit);
446
      PP_PORT1 &= ~(1<<STEP_X);
447
      delay_us(geschwindigkeit);
448
      i++;
449
    }
450
    PP_PORT2 |= (1<<ENABLE);
451
    break;
452
    
453
    case 8:
454
    PP_PORT1 |= (1<<DIR_Z);
455
    _delay_us(1);
456
    PP_PORT2 &= ~(1<<ENABLE);
457
    _delay_us(1);
458
    while (i<step)
459
    {
460
      PP_PORT1 |= (1<<STEP_Z);
461
      delay_us(geschwindigkeit);
462
      PP_PORT1 &= ~(1<<STEP_Z);
463
      delay_us(geschwindigkeit);
464
      i++;
465
    }
466
    PP_PORT2 |= (1<<ENABLE);
467
    break;
468
    
469
    case 9:
470
    PP_PORT1 &= ~((1<<DIR_X)|(1<<DIR_Y));
471
    _delay_us(1);
472
    PP_PORT2 &= ~(1<<ENABLE);
473
    _delay_us(1);
474
    while (i<step)
475
    {
476
      PP_PORT1 |= ((1<<STEP_X)|(1<<STEP_Y));
477
      delay_us(geschwindigkeit);
478
      PP_PORT1 &= ~((1<<STEP_X)|(1<<STEP_Y));
479
      delay_us(geschwindigkeit);
480
      i++;
481
    }
482
    PP_PORT2 |= (1<<ENABLE);
483
    break;
484
    
485
    case 10:
486
    PP_PORT1 &= ~(1<<DIR_Y);
487
    _delay_us(1);
488
    PP_PORT2 &= ~(1<<ENABLE);
489
    _delay_us(1);
490
    while (i<step)
491
    {
492
      PP_PORT1 |= (1<< STEP_Y);
493
      delay_us(geschwindigkeit);
494
      PP_PORT1 &= ~(1<<STEP_Y);
495
      delay_us(geschwindigkeit);
496
      i++;
497
    }
498
    PP_PORT2 |= (1<<ENABLE);
499
    break;
500
    
501
    case 11:
502
    PP_PORT1 |= (1<<DIR_X);
503
    PP_PORT1 &= ~(1<<DIR_Y);
504
    _delay_us(1);
505
    PP_PORT2 &= ~(1<<ENABLE);
506
    _delay_us(1);
507
    while (i<step)
508
    {
509
      PP_PORT1 |= ((1<<STEP_X)|(1<< STEP_Y));
510
      delay_us(geschwindigkeit);
511
      PP_PORT1 &= ~((1<<STEP_X)|(1<< STEP_Y));
512
      delay_us(geschwindigkeit);
513
      i++;
514
    }
515
    PP_PORT2 |= (1<<ENABLE);
516
    break;
517
    
518
    case 12:
519
    //unbenutzt
520
    break;
521
    
522
    case 13:
523
    PP_PORT1 &= ~(1<<DIR_A);
524
    _delay_us(1);
525
    PP_PORT2 &= ~(1<<ENABLE);
526
    _delay_us(1);
527
    while (i<step)
528
    {
529
      PP_PORT2 |= (1<<STEP_A);
530
      delay_us(geschwindigkeit);
531
      PP_PORT2 &= ~(1<<STEP_A);
532
      delay_us(geschwindigkeit);
533
      i++;
534
    }
535
    PP_PORT2 |= (1<<ENABLE);
536
    break;
537
    
538
    case 14:
539
    PP_PORT1 |= (1<<DIR_A);
540
    _delay_us(1);
541
    PP_PORT2 &= ~(1<<ENABLE);
542
    _delay_us(1);
543
    while (i<step)
544
    {
545
      PP_PORT2 |= (1<<STEP_A);
546
      delay_us(geschwindigkeit);
547
      PP_PORT2 &= ~ (1<<STEP_A);
548
      delay_us(geschwindigkeit);
549
      i++;
550
    }
551
    PP_PORT2 |= (1<<ENABLE);
552
    break;
553
  }
554
  if (STUFE_PIN2&(1<<STUFE11))
555
  {
556
    taste = 0;
557
  }  
558
  return (0);
559
}
560
561
562
int main(void)
563
{
564
  uC_Init();
565
  sei();
566
  while(1)
567
  {
568
    Matrix ();
569
    Stufenschalter();
570
    Stepper();
571
  }  
572
  return (0);
573
}

von Michael D. (etzen_michi)


Lesenswert?

Das Programm hättest du besser als Anhang gemacht.

von MaWin (Gast)


Lesenswert?

Und wie mischt du PC-Signale und Tastatursignale ?
Stecker abziehen und wechseln ?

Das ist nämlich das Problem der chinesischen TB6560 Boards,
die mischen auf eher nicht funktionierende Art.

Wenn man die Signale ODER verknüpft (oder UND verknüpft bei
negativer Logik) und der PC das Taktsignal noch auf high hat
kann man nicht manuell fahren. Hält der PC das Richtungssignal
der letzten Bewegung, kann man nicht in Gegenrichtung fahren
sondern die Fräse bewegt sich in die andere als gewünschte
Richtung.

Wenn man XOR verknüpft, und der PC das Richtungssignal hält,
bewegt sich alles in die verkehrte Richtung.

Wenn man einen Umschalter für die Signale hat, muss man eben
umschalten (scheint mir die einzig praktikable Methode zu sein).

Bei Bewegungen sollte man eine Beschleunigungsrampe im Programm
beachten, damit man nicht nur im Kriechgang fahren kann.
Die Beschleunigungsrampe heisst aber auch, daß man über das
Ziel hinausschiesst weil man ja bremsen muss. Da könnte der
Benutzer schon den Knopf für die andere Richtung drücken.

Und aus Erfahrung: Verbaue bessere Taster.

von Axel L. (lemmi4711)


Lesenswert?

@MaWin:

Die Signale werden nicht gemischt!!!
Ich habe einen DB25-Umschalter zwischengeschaltet, der alle 25 Pole 
manuell umschaltet...

Die Beschleunigungsrampen werden übrigens in der Motorsteuerung 
realisiert.

@Michael:

Drag&Drop??? - schon mal gehört???    ;-)

@Bee: Na, weil keiner vorhanden war?!?
Wenn Du willst, kannst DU das Programm gerne dafür anpassen.
Für MEINE Zwecke waren Taster einfacher UND dafür vorhanden....

@All:

Diese Handsteuerung war von mir als einfache CNC Steuerung gedacht um 
mal schnell kleine einfache Langlöcher, Taschen, usw. zu fräsen OHNE es 
erst auf dem PC planen zu müssen.
Sonst wäre es von Hand schneller... :-P

Auch kann man damit die Funktion der Maschine testen......
(Die Wege müsses natürlich im Programm angepasst werden!)

von Uwe (Gast)


Lesenswert?

Wie wärs mit Inkrementalgebern ?!

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.