Mein erstes Projekt: Ein Punktschweißgerät zum Akkus bauen

Hallo,

ich möchte zum ersten Mal im Leben was programmieren und habe mir gleich was Sinnvolles ausgesucht: ein Punktschweißtgerät.

Im Endeffekt funktioniert es so, dass ein Fet-Treiber 6 Fets parallel für ein paar ms aufmacht und einen 12V Batterieblock über 2 Elektroden kurzschließt. Ich habe mit so etwas schon gebastelt, es funktioniert von der Technik her sehr gut für meine Anwendung. Thyristoren, Kondensatoren etc. sind dafür nicht nötig, aber auch nicht das, was ich diskutieren möchte.

Was ich erreichen möchte:

  • Einen Puls von 20-500ms mit zwei Tasten einstellen und durch Tastendruck auslösen
  • Eine Pause zwischen dem ersten und dem Zweiten Puls von 10-200 ms mit zwei Tasten einstellen
  • Einen zweiten Puls von 20-500ms mit zwei Tasten einstellen
  • Einstellung der 3 Werte auf einem Display darstellen
  • Spannung des Versorgungsakkus (ca. 12V) auf Display darstellen.

Gegenwärtiger Stand.
Ich habe letzte Nacht meine ersten (!) Zeilen Code geschrieben, die vielleicht schon mal für einen Puls funktionieren würden.

const int fetPin =  A0;      
const int butttonPin = A1;
const int increasePin = A2;
const int decreasePin =A3;

int fetState = LOW;    
int buttonState = LOW;
int increaseState = LOW;
int decreaseState = LOW;
int previousMillis = 0;        
int interval = 50;           

void setup() {

  pinMode(fetPin, OUTPUT);
  pinMode(butttonPin, INPUT);  
}

void loop()
{
if(digitalRead(buttonState) == HIGH)
    fetState = HIGH;
  else
      fetState = LOW;
  digitalWrite(fetPin, fetState);
     unsigned int currentMillis = millis();
  
  if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
        fetState = LOW;
  digitalWrite(fetPin, fetState);
   }
   if(increaseState = HIGH)
   interval + 5;
   if(interval > 500)
   interval = 500;
   if(decreaseState = HIGH)
   interval - 5;
   if(interval < 20)
   interval = 20;
  digitalWrite(fetPin, fetState);
   }
}

Mein erstes Problem ist, dass ich befürchte, dass das, wenn ich die Taste länger gedrückt halte, mehrere Pulse auslöst und nicht nur einen.

Mein zweites Problem ist am Nokia Display, das ich angeschlossen habe. Ich kann mittlerweile Zeichen darstellen, aber ich schaffe es nicht, die Variable darstellen zu lassen.

#include <HW_ARM_defines.h>
#include <HW_AVR_defines.h>
#include <HW_PIC32_defines.h>
#include <LCD5110_Basic.h>

int p1 = 555;
int d1 = 556;
int p2 = 557;

 
// The pins to use on the arduino
#define PIN_SCE   12
#define PIN_RESET 11
#define PIN_DC    10
#define PIN_SDIN  9
#define PIN_SCLK  8
 
// COnfiguration for the LCD
#define LCD_C     LOW
#define LCD_D     HIGH
#define LCD_CMD   0
 
// Size of the LCD
#define LCD_X     84
#define LCD_Y     48
 
int scrollPosition = 0;
 
static const byte ASCII[][5] =
{
 {0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ?
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f ?
};
 
void LcdCharacter(char character)
{
  LcdWrite(LCD_D, 0x00);
  for (int index = 0; index < 5; index++)
  {
    LcdWrite(LCD_D, ASCII[character - 0x20][index]);
  }
  LcdWrite(LCD_D, 0x00);
}
 
void LcdClear(void)
{
  for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
  {
    LcdWrite(LCD_D, 0x00);
  }
}
 
void LcdInitialise(void)
{
  pinMode(PIN_SCE,   OUTPUT);
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC,    OUTPUT);
  pinMode(PIN_SDIN,  OUTPUT);
  pinMode(PIN_SCLK,  OUTPUT);
 
  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_RESET, HIGH);
 
  LcdWrite(LCD_CMD, 0x21);  // LCD Extended Commands.
  LcdWrite(LCD_CMD, 0xBf);  // Set LCD Vop (Contrast). //B1
  LcdWrite(LCD_CMD, 0x04);  // Set Temp coefficent. //0x04
  LcdWrite(LCD_CMD, 0x14);  // LCD bias mode 1:48. //0x13
  LcdWrite(LCD_CMD, 0x0C);  // LCD in normal mode. 0x0d for inverse
  LcdWrite(LCD_C, 0x20);
  LcdWrite(LCD_C, 0x0C);
}
 
void LcdString(char *characters)
{
  while (*characters)
  {
    LcdCharacter(*characters++);
  }
}
 
void LcdWrite(byte dc, byte data)
{
  digitalWrite(PIN_DC, dc);
  digitalWrite(PIN_SCE, LOW);
  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
  digitalWrite(PIN_SCE, HIGH);
}
 
/**
 * gotoXY routine to position cursor
 * x - range: 0 to 84
 * y - range: 0 to 5
 */
void gotoXY(int x, int y)
{
  LcdWrite( 0, 0x80 | x);  // Column.
  LcdWrite( 0, 0x40 | y);  // Row.
}
 
 
void setup(void)
{
  LcdInitialise();
  LcdClear();
  
 
}
 
void loop(void)
{
gotoXY(1,1);
  LcdString("P1:");
gotoXY(30,1);
itoa (d1,
  LcdString(p1); 
  
gotoXY(57,1);
  LcdString(" ms");

gotoXY(1,3);
  LcdString("Dl:");
gotoXY(30,3);
  LcdString(d1); 
gotoXY(65,3);
  LcdString("ms"); 
  
gotoXY(1,5);
  LcdString("P2:");
gotoXY(30,5);
  LcdString(p2); 
gotoXY(65,5);
  LcdString("ms"); 
}

Meine dritte Baustelle ist das Display.
Das Nokia Display gefällt mir nicht, es ist zu klein, hat keine eingebauten Tasten etc.

Ich würde vielleicht gerne so einen 3.2" Touchscreen nehmen.
Ist das zu kompliziert für den Anfang? Gibt es dafür Einbaurahmen oder Gehäuse?
Ich benutze im Moment einen Arduino Nano, soll ich einfach mal einen Uno kaufen, der lässt sich wohl direkt auf das Display stecken. Den Nano kann ich anderweitig gebrauchen.

Welches Nokia Display hast Du?

Du könntest ein LCD display mit 2x20 oder 4x20 Zeichen nehmen (HD44780 kompatibel).
Die sind auch groß zu haben und einfach anzusteuern.

Ein 3.2" Touchscreen Farb Display braucht viel RAM. Da brauchst Du wahrscheinlich einen Arduino Mega. Das scheint mit für den anfang etwas schwierig und programmmäßig eine grüßeres Projekt.

kleinere Fehler:
"unsigned int currentMillis = millis();" Bitte variablentyp unsigned long nehmen.
"if(digitalRead(buttonState) == HIGH)" buttonstate ist nicht das pin des Tasters sondern butttonPin

Grüße Uwe

Hallo Uwe,

vielen Dank für die Antwort.
Ich dachte, dass long nicht nötig ist, weil es im Zweifel einen overflow gibt und Werte über 2000ms nicht wichtig sind.

Ich habe den Code (hoffentlich richtig) geändert-
Wenn ich es richtig verstehe, muss ich das bei “increase” und “decrease” auch ändern. Das habe ich mal gemacht.

const int fetPin =  A0;      
const int buttonPin = A1;
const int increasePin = A2;
const int decreasePin =A3;
const int sensorValue = analogRead(A4);

int fetState = LOW;    

int increaseState = LOW;
int decreaseState = LOW;
int previousMillis = 0;        
int interval = 50;           




void setup() {
  Serial.begin(9600);

  pinMode(fetPin, OUTPUT);
  pinMode(buttonPin, INPUT);  

}

void loop(){
  float voltage= sensorValue * (5.0 / 1024.0);
  Serial.println(voltage);

  if(digitalRead(buttonPin) == HIGH)
    fetState = HIGH;
    else
      fetState = LOW;
    digitalWrite(fetPin, fetState);
    unsigned long int currentMillis = millis();

    if(currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;
      fetState = LOW;
      digitalWrite(fetPin, fetState);
    }
    if(increasePin == HIGH)
      interval + 5;
    if(interval > 500)
      interval = 500;
    if(decreasePin == HIGH)
      interval - 5;
    if(interval < 20)
      interval = 20;
    digitalWrite(fetPin, fetState);
  }
}

Wegen dem Display wäre das 4-Zeilen-Display leicht ausreichend.
Ich bräuchte dann halt irgendein Tastenfeld dazu und nach Möglichkeit einen Einbaurahmen für beides.

Ich habe ein Nokia 5110 LCD Breakout Display.
Ich habe den Nano und das Display eigentlich für den “Forumscontroller” für Pedelecs gekauft. Ich möchte den aber mit einem Android Handy auslesen und muss dafür erst noch die Basics im Arduino programmieren lernen. Das mit dem Fahrrad kommt dann hoffentlich später. :slight_smile:
Auf dem Display kann ich mit dem Code von oben drei Zeilen darstellen, allerdings relativ klein.
Für einen ersten Test und bis ein anderes Display beschafft ist, würde es mir reichen, das Display zu nehmen. Der Code für die Pulsdauern und die Pausen ändert sich ja dadurch nicht :slight_smile:

const int sensorValue = analogRead(A4); außerhalb der Funktionen funktioniert nicht. Außerdem kann eine Constant-Variable nicht geändert werden.
float voltage= sensorValue * (5.0 / 1024.0); Du mußt durch 1023 teilen.
Auch int previousMillis = 0; muß unsigned long sein.

if(digitalRead(buttonPin) == HIGH)
    fetState = HIGH;
    else
    fetState = LOW;
    digitalWrite(fetPin, fetState);

Schaltet den Ausgang analog zum Taster ein/aus. Da hast Du kein Start der Schweißzeit.

unsigned long int currentMillis = millis();

Definiere den Typ der Variable am Anfang.

float voltage= sensorValue * (5.0 / 1024.0);
  Serial.println(voltage);

Willst Du hier die Batteriespannung ausgeben? Ist diese nicht 12V? Du mußt das Übersetzungsverhältnis des Spannungsteilers berücksichtigen. Arduino kann keine Spannungen über 5V messen (bei 5V Spannungsversorgung) Bei größeren Spannungen geht er kaputt.

Du mußt die Taster entprellen. Außerden ist es besser in der Tastaturabfrage eine Verzögerung einzubauen. Sonst brauchst Du einen superschnellen Superman um die Taste im richtigen Moment loszulassen. :wink:

digitalWrite(fetPin, fetState); Am Ende ist überflüssig.

Grüße Uwe

uwefed:
const int sensorValue = analogRead(A4); außerhalb der Funktionen funktioniert nicht. Außerdem kann eine Constant-Variable nicht geändert werden.

Da hast Du natürlich recht.

uwefed:
float voltage= sensorValue * (5.0 / 1024.0); Du mußt durch 1023 teilen.
Auch int previousMillis = 0; muß unsigned long sein.

Ich dachte die 0 zähltmit dazu und es sind daher 1024 Stufen. Aber ok.

uwefed:

if(digitalRead(buttonPin) == HIGH)

fetState = HIGH;
    else
    fetState = LOW;
    digitalWrite(fetPin, fetState);



Schaltet den Ausgang analog zum Taster ein/aus. Da hast Du kein Start der Schweißzeit.

Ich suche mal nach einer Funktion, die Millis() triggert und nach einer, die den aktuellen Wert mit dem von vorher vergleicht.
Wenn Du meine Suche verkürzen möchtest, sehr gerne :slight_smile:

uwefed:

unsigned long int currentMillis = millis();

Definiere den Typ der Variable am Anfang.

ok

uwefed:

float voltage= sensorValue * (5.0 / 1024.0);

Serial.println(voltage);



Willst Du hier die Batteriespannung ausgeben? Ist diese nicht 12V? Du mußt das Übersetzungsverhältnis des Spannungsteilers berücksichtigen. Arduino kann keine Spannungen über 5V messen (bei 5V Spannungsversorgung) Bei größeren Spannungen geht er kaputt.

Die Akkuspannung ist tatsächlich ca. 12V (3s8p)
Ich habe einen LM2596HV, mit dem kann ich dem Arduino stabil 5V geben.
Ich habe verschiedene Widerstände da. Ich bin aber noch nicht sicher, welche Werte ich da brauche.
Wenn ich das Prinzip des Spannungsteilers richtig verstehe, nehme ich drei gleichstarke Widerstände, klemme die in Reihe zwischen Plus und Masse. Nach dem ersten mache ich eine Abzweigung zum Analogpin. Dann sollte der Pin bei 5V 1023 ausgeben, oder?
Wie schließe ich denn den Spannungsteiler an, so dass er mir nicht im Ruhezustand die Batterie leerzieht? Trennt der Arduino auch die MassePins? Oder definiere ich einen Pin als low und schließe da die Widerstandskette an?

uwefed:
Du mußt die Taster entprellen. Außerden ist es besser in der Tastaturabfrage eine Verzögerung einzubauen. Sonst brauchst Du einen superschnellen Superman um die Taste im richtigen Moment loszulassen. :wink:

Dazu habe ich schon was gelesen. Magst Du mir einen Tipp geben, welche Funktion ich dafür nehmen könnte. Dann recherchiere ich, wie das gehen könnte.

uwefed:
digitalWrite(fetPin, fetState); Am Ende ist überflüssig.

Grüße Uwe

Dann muss im VoidSetup oder am Anfang des Voidloops der fetPin immer low gesetzt werden, oder?

Vielen Dank Dir schon mal auf alle Fälle. Das hilft mir sehr.

Ich war, wie ich finde sehr fleißig und habe mir das mit dem Entprellen und mir das mit den if-Abfragen angeschaut.
Wenn ich mich nicht täusche, habe ich den ersten Teil schon geschafft.

Eine Taste soll die Schweißimpulsfolge auslösen.
Je eine Taste soll je den ersten, den zweiten Schweißimpuls und die Pause dazwischen in Grenzen nach oben und unten regeln.
Alle Tasten sollten jetzt softwaremäßig entprellt sein.

Könnte das mal jemand anschauen, ob das so passen könnte?
Dann kümmere ich mich mal um den Rest.

// Pin naming

int fetPin =  A0;      
int TriggerPin = 3;
int increase1Pin = 4;
int decrease1Pin = 5;
int increase2Pin = 6;
int decrease2Pin = 7;
int increase3Pin = 8;
int decrease3Pin = 9;

// voltage sensor for later
int sensorValue = analogRead(A1);
int fetState = LOW;    

unsigned long debounceDelay = 50;    

unsigned long duration1 = 50;  
unsigned long duration1new = 0;
unsigned long upperlimitduration1 = 0;
unsigned long lowerlimitduration1 = 950;

unsigned long duration2 = 50;
unsigned long duration2new = 0;
unsigned long upperlimitduration2 = 0;
unsigned long lowerlimitduration2 = 500;

unsigned long duration3 = 200;
unsigned long duration3new = 0;
unsigned long upperlimitduration3 = 0;
unsigned long lowerlimitduration3 = 950;


int interval = 10;



unsigned long readingtrigger = 0;
unsigned long readingincrease1 = 0;
unsigned long readingincrease2 = 0;
unsigned long readingincrease3 = 0;
unsigned long readingdecrease1 = 0;
unsigned long readingdecrease2 = 0;
unsigned long readingdecrease3 = 0;


unsigned long TriggerState = LOW;
unsigned long lastTriggerState = LOW;
unsigned long lastDebounceTime = 0;  

unsigned long increase1State = LOW;
unsigned long lastincrease1State = LOW;
unsigned long lastDebounceTime1 = 0;

unsigned long increase2State = LOW;
unsigned long lastincrease2State = LOW;
unsigned long lastDebounceTime2 = 0;

unsigned long increase3State = LOW;
unsigned long lastincrease3State = LOW;
unsigned long lastDebounceTime3 = 0;

unsigned long decrease1State = LOW;
unsigned long lastdecrease1State = LOW;
unsigned long lastDebounceTime4 = 0;

unsigned long decrease2State = LOW;
unsigned long lastdecrease2State = LOW;
unsigned long lastDebounceTime5 = 0;

unsigned long decrease3State = LOW;
unsigned long lastdecrease3State = LOW;
unsigned long lastDebounceTime6 = 0;





void setup() {

Serial.begin(9600);

// declaring pins as input and output
pinMode(fetPin, OUTPUT);
pinMode(TriggerPin, INPUT);  
pinMode(increase1Pin, INPUT); 
pinMode(decrease1Pin, INPUT); 
pinMode(increase2Pin, INPUT); 
pinMode(decrease2Pin, INPUT); 
pinMode(increase3Pin, INPUT); 
pinMode(decrease3Pin, INPUT); 
}

void loop()
{
// debouncing the Trigger
readingtrigger = digitalRead(TriggerPin);

  if (readingtrigger != lastTriggerState) 
     {lastDebounceTime = millis();  }
  if ((millis() - lastDebounceTime) > debounceDelay) 
     {TriggerState = readingtrigger;}

// triggering fetPin
digitalWrite(fetPin, TriggerState);
//  getting trigger time
unsigned long triggertime = millis();
// switching off pulse 1
if (millis() - triggertime > duration1);
digitalWrite (fetPin, LOW);

// Triggering the Fet again, when the first pulse and the pause are over, but only if pulse 2 is a positive number. No pulse for second pulse = 0 
if (millis() - triggertime > duration1 + duration2
&& (duration2 > 0));
digitalWrite (fetPin, HIGH);
// final switch off
if (millis() - triggertime > duration1 + duration2 + duration3);
digitalWrite (fetPin, LOW);


// debouncing button increase pulse 1
{
readingincrease1 = digitalRead(increase1Pin);

  if (readingincrease1 != lastincrease1State) 
     {lastDebounceTime1 = millis();  }
  if ((millis() - lastDebounceTime1) > debounceDelay)
     {increase1State = readingincrease1;}
}

// debouncing button increase pulse 2
{
readingincrease2 = digitalRead(increase2Pin);

  if (readingincrease2 != lastincrease2State) 
     {lastDebounceTime2 = millis();  }
  if ((millis() - lastDebounceTime2) > debounceDelay)
     {increase1State = readingincrease2;}
}

// debouncing button increase pulse 3
{
readingincrease3 = digitalRead(increase3Pin);

  if (readingincrease3 != lastincrease3State) 
     {lastDebounceTime3 = millis();  }
  if ((millis() - lastDebounceTime3) > debounceDelay)
     {increase1State = readingincrease3;}
}


// debouncing button decrease pulse 1
{
readingdecrease1 = digitalRead(decrease1Pin);

  if (readingdecrease1 != lastdecrease1State) 
     {lastDebounceTime4 = millis();  }
  if ((millis() - lastDebounceTime1) > debounceDelay)
     {decrease1State = readingdecrease1;}
}

// debouncing button decrease pulse 2
{
readingdecrease2 = digitalRead(decrease2Pin);

  if (readingdecrease2 != lastdecrease2State) 
     {lastDebounceTime5 = millis();  }
  if ((millis() - lastDebounceTime2) > debounceDelay)
     {decrease1State = readingdecrease2;}
}

// debouncing button decrease pulse 3
{
readingdecrease3 = digitalRead(decrease3Pin);

  if (readingdecrease3 != lastdecrease3State) 
     {lastDebounceTime6 = millis();  }
  if ((millis() - lastDebounceTime3) > debounceDelay)
     {decrease1State = readingdecrease3;}
}



// increasing pulse 1
{
if ((increase1State == HIGH) && (duration1 < upperlimitduration1))
    {duration1new = duration1 + interval;}
    else {duration1new = duration1;}
digitalWrite (duration1, duration1new);
}


// increasing pulse 2
{
if ((increase2State == HIGH) && (duration1 < upperlimitduration2))
    {duration2new = duration2 + interval;}
    else {duration2new = duration2;}
digitalWrite (duration2, duration2new);
}


// increasing pulse 3
{
if ((increase3State == HIGH) && (duration1 < upperlimitduration3))
    {duration3new = duration3 + interval;}
    else {duration3new = duration3;}
digitalWrite (duration3, duration3new);
}


// decreasing pulse 1
{
if ((decrease1State == HIGH) && (duration1 > lowerlimitduration1))
    {duration1new = duration1 + interval;}
    else {duration1new = duration1;}
digitalWrite (duration1, duration1new);
}


// decreasing pulse 2
{
if ((decrease2State == HIGH) && (duration1 > lowerlimitduration2))
    {duration2new = duration2 + interval;}
    else {duration2new = duration2;}
digitalWrite (duration2, duration2new);
}

// decreasing pulse 3
{
if ((decrease3State == HIGH) && (duration3 > lowerlimitduration3))
    {duration3new = duration3 + interval;}
    else {duration3new = duration3;}
digitalWrite (duration3, duration3new);
}



}

Deus_Ex_Machina:
Könnte das mal jemand anschauen, ob das so passen könnte?

Am einfachsten, du baust das Ganze auf, anstelle der HochleistungsMosFets steuerst du eine LED an.

dann kannst du sehen, was dein Ausgang macht, ohne dass dir was in Rauch aufgeht.
Die interessanten Variablen kannst du dir mir "Serial.print" auf dem Monitor ausgeben.

erst beim Test wirst du deine Fehler finden. Sowohl die Codierfehler, als auch die Denkfehler.

Grüße

Gunther

Aus Neugier: warum braucht man zwei einstellbare Impulse + einstellbare Länge? Kannst Du das so erklären damit jemand der keine Ahnung davon hat das versteht? Sobald ich das dann verstanden habe baue ich vieleicht auch mal so ein Teil :wink:

Hallo Udo,

eigentlich braucht man nur einen Impuls. Das reicht schon.
Ich habe schon über 1000 Punktschweißungen mit einem Puls gemacht. Das hat wunderbar geklappt. Ich schicke Dir gern Bilder von einem Akku, wenn Du möchtest.
Einige sagen allerdings, dass ein kleiner Vor-Impuls die Kontakte reinigt und die Kupferelektroden dann nicht mehr in dem Maß auf auf dem Band kleben bleiben. Der zweite Impuls schweißt die beiden Schichten dann wirklich zusammen. Nötig ist es daher also nicht, aber ein bisschen besser.
Was aber schon nötig ist, ist das Regeln der Schweißzeit. Je nach Dicke des Bandes und Material braucht es andere Schweißzeiten.

Ich mache das Ganze um Akkus für Elektrofahrräder zu bauen. Im Prinzip kann man damit aber z.B. auch wieder Notebook-Akkus etc. fit machen.
Falls Du auch so ein Gerät bauen möchtest, kannst Du mich wegen Zellen (zur Versorgung der Schweißgerätes oder auch für die Akkus selbst) gedrehten Kupferelektroden ansprechen. Habe ich mir alles schon besorgt und ist evtl. nicht einfach und günstig zu beschaffen.

Bei den 18650 Akkus ist das Löten teilweise problematisch und sehr schwierig, da die Zellen temperaturempfindlich sind, und den Lötdraht ohne Aufrauen nicht annehmen. Daher lohnt sich der Bau so eines Schweißgerätes sehr schnell.

Ich möchte das Display hier verwenden
http://www.ebay.de/itm/Neu-SainSmart-Mega2560-12864-LCD-Sensor-Shield-V5-Kit-For-Arduino-AVR-ATmega8U2-/230955016082?pt=Wissenschaftliche_Geräte&hash=item35c5fddf92

Meinst Du, ich kann schnell genug lernen ein Menu zur Auswahl des Werts zu programmieren, damit ich das hier benutzen kann?
http://www.ebay.de/itm/SainSmart-UNO-LCD1602-Keypad-Shield-Prototype-Shield-Starter-Kit-For-Arduino-/230939809419?pt=AU_B_I_Electrical_Test_Equipment&hash=item35c515d68b

Ich würde dann grundsätzlich die Akkuspannung und die Dauer der 3 Impulse anzeigen lassen und in einem Menü die Dauer der Pulse regeln.
Da es das erste mal ist, dass ich etwas programmiere, weiß ich nicht, ob das für den Anfang realistisch ist. Die gesamte Code, den ich in meinem Leben geschrieben habe, steht in diesem Thread :frowning:

Deus_Ex_Machina
Fang mal mit 1 Zähler an und nicht gleich mit 3.

Vorher waren die Variablen in denen die Werte von millis() gespeichert wurden zu klein definiert: jetzt hast Du Statusvariablen die HIGH oder LOW sein können als unsigned long definiert. Übertreib nicht so.

readingtrigger = digitalRead(TriggerPin);// debouncing the Trigger
  if (readingtrigger != lastTriggerState) 
     {lastDebounceTime = millis();  }
  if ((millis() - lastDebounceTime) > debounceDelay) 
     {TriggerState = readingtrigger;}

ist die Triggerzeit vergangen wird TriggerState mit dem Zustand des Tasters geladen Also geht der Ausgang nicht nach einer gewissen zeit aus sondern wenn der Taster losgelassen wird.

Zum Entprellen brauchst Du kein millis. Da genügt delay().

Grüße Uwe

uwefed:
Deus_Ex_Machina
Fang mal mit 1 Zähler an und nicht gleich mit 3.

Vorher waren die Variablen in denen die Werte von millis() gespeichert wurden zu klein definiert: jetzt hast Du Statusvariablen die HIGH oder LOW sein können als unsigned long definiert. Übertreib nicht so.

Egal wie ich's mache ist es falsch :wink:
Ich hab's korrigiert.

uwefed:

readingtrigger = digitalRead(TriggerPin);// debouncing the Trigger

if (readingtrigger != lastTriggerState)
    {lastDebounceTime = millis();  }
  if ((millis() - lastDebounceTime) > debounceDelay)
    {TriggerState = readingtrigger;}


ist die Triggerzeit vergangen wird TriggerState mit dem Zustand des Tasters geladen Also geht der Ausgang nicht nach einer gewissen zeit aus sondern wenn der Taster losgelassen wird.

Ich versuche das mal zu ändern und schicke gleich nochmal den Code.
Ich glaube ich verstehe den Fehler.

uwefed:
Zum Entprellen brauchst Du kein millis. Da genügt delay().

Grüße Uwe

Delay wollte ich absichtlich nicht nehmen, da ja eine Anzeige betrieben wird. Würde die während der delay Phase ausgehen oder weiter den Wert von vorher zeigen?
Kann ich eigentlich mehrere void voops parallel laufen lassen, damit die einzelnen Funktionen übersichtlicher werden?

Delays fürs entprellen müssen nur 5-10mS lang sein. Das stört die Tastatureingabe oder Display nicht. Der Delay wird ja auch nur beim ersten Tastendruck ausgeführt.
Grüße Uwe

Ah, ok, danke Dir.
Ich habe versucht, den Fehler zu beheben.
Ich bin im Kopf nochmal alles durchgegangen und habe es durchgespielt.
So sollte es jetzt funktionieren.

void loop()
{
// debouncing the Trigger
readingtrigger = digitalRead(TriggerPin);
if (readingtrigger != lastButtonState) {
    lastDebounceTime = millis();}
  if ((millis() - lastDebounceTime) > debounceDelay) 
     {TriggerState = readingtrigger;}

// triggering fetPin
if (TriggerState == HIGH && lastButtonState == LOW); 
{digitalWrite(fetPin, HIGH);
//  getting trigger time
triggertime = millis();
// switching off pulse 1
if (millis() - triggertime > duration1);
digitalWrite (fetPin, LOW);
}

// Triggering the Fet again, when the first pulse and the pause are over, but only if pulse 2 is a positive number. No pulse for second pulse = 0 
if (millis() - triggertime > duration1 + duration2
&& (duration2 > 0));
digitalWrite (fetPin, HIGH);
// final switch off
if (millis() - triggertime > duration1 + duration2 + duration3);
digitalWrite (fetPin, LOW);

Kann mir noch einer einen Tipp geben, wo ich mich einlesen kann, wie ich am Display (es wird ein 20x4 Display) was darstellen kann?

Ich habe jetzt das Nokia Display schon mal so weit am laufen, dass ich die drei Integer-Werte korrekt dargestellt bekomme. Was nicht funktioniert, ist die Funktion des Tasters.

Ich habe einen Taster und einen 8k8 Widerstand in Reihe zwischen D4 und 5V.
Die Spannungsversorgung für den Arduino ist auf 7V eingestellt.

Wenn ich den Taster drücke, passiert nichts. Habe ich das mit dem PullUp-Widerstand falsch verstanden?

Hier noch der momentane Code:

#include <HW_ARM_defines.h>
#include <HW_AVR_defines.h>
#include <HW_PIC32_defines.h>
#include <LCD5110_Basic.h>


int fetPin =  13;      
int TriggerPin = 3;
int increase1Pin = 4;
int decrease1Pin = 5;
int increase2Pin = 6;
int decrease2Pin = 7;
int increase3Pin = 8;
int decrease3Pin = 9;


unsigned long debounceDelay = 50;    

unsigned long duration1 = 50;  
unsigned long duration1new = 0;
unsigned long upperlimitduration1 = 2000;
unsigned long lowerlimitduration1 = 0;

unsigned long duration2 = 50;
unsigned long duration2new = 0;
unsigned long upperlimitduration2 = 0;
unsigned long lowerlimitduration2 = 500;

unsigned long duration3 = 200;
unsigned long duration3new = 0;
unsigned long upperlimitduration3 = 0;
unsigned long lowerlimitduration3 = 950;


int interval = 10;

unsigned long readingtrigger = 0;
unsigned long readingincrease1 = 0;
unsigned long readingincrease2 = 0;
unsigned long readingincrease3 = 0;
unsigned long readingdecrease1 = 0;
unsigned long readingdecrease2 = 0;
unsigned long readingdecrease3 = 0;


int TriggerState = LOW;
int lastTriggerState = LOW;
unsigned long lastDebounceTime = 0;  
unsigned long triggertime = 0;

int increase1State = LOW;
int lastincrease1State = LOW;
unsigned long lastDebounceTime1 = 0;

unsigned long increase2State = LOW;
unsigned long lastincrease2State = LOW;
unsigned long lastDebounceTime2 = 0;

unsigned long increase3State = LOW;
unsigned long lastincrease3State = LOW;
unsigned long lastDebounceTime3 = 0;

unsigned long decrease1State = LOW;
unsigned long lastdecrease1State = LOW;
unsigned long lastDebounceTime4 = 0;

unsigned long decrease2State = LOW;
unsigned long lastdecrease2State = LOW;
unsigned long lastDebounceTime5 = 0;

unsigned long decrease3State = LOW;
unsigned long lastdecrease3State = LOW;
unsigned long lastDebounceTime6 = 0;


void setup() {

  Serial.begin(9600);



  // declaring pins as input and output
  pinMode(fetPin, OUTPUT);
  pinMode(TriggerPin, INPUT);  
  pinMode(increase1Pin, INPUT); 
  pinMode(decrease1Pin, INPUT); 
  pinMode(increase2Pin, INPUT); 
  pinMode(decrease2Pin, INPUT); 
  pinMode(increase3Pin, INPUT); 
  pinMode(decrease3Pin, INPUT); 



  LcdInitialise();
  LcdClear();


}

void loop()
´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´
{
  // debouncing the Trigger
  readingtrigger = digitalRead(TriggerPin);
  if (readingtrigger != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) 
  {
    TriggerState = readingtrigger;
  }

  // triggering fetPin
  if (TriggerState == HIGH && lastButtonState == LOW); 
  {
    digitalWrite(fetPin, HIGH);
    //  getting trigger time
    triggertime = millis();
    // switching off pulse 1
    if (millis() - triggertime > duration1);
    digitalWrite (fetPin, LOW);
  }

  // Triggering the Fet again, when the first pulse and the pause are over, but only if pulse 2 is a positive number. No pulse for second pulse = 0 
  if (millis() - triggertime > duration1 + duration2
    && (duration2 > 0));
  digitalWrite (fetPin, HIGH);
  // final switch off
  if (millis() - triggertime > duration1 + duration2 + duration3);
  digitalWrite (fetPin, LOW);


  // debouncing button increase pulse 1
  {
    readingincrease1 = digitalRead(increase1Pin);

    if (readingincrease1 != lastincrease1State) 
    {
      lastDebounceTime1 = millis();  
    }
    if ((millis() - lastDebounceTime1) > debounceDelay)
    {
      increase1State = readingincrease1;
    }
  }

  // debouncing button increase pulse 2
  {
    readingincrease2 = digitalRead(increase2Pin);

    if (readingincrease2 != lastincrease2State) 
    {
      lastDebounceTime2 = millis();  
    }
    if ((millis() - lastDebounceTime2) > debounceDelay)
    {
      increase1State = readingincrease2;
    }
  }

  // debouncing button increase pulse 3
  {
    readingincrease3 = digitalRead(increase3Pin);

    if (readingincrease3 != lastincrease3State) 
    {
      lastDebounceTime3 = millis();  
    }
    if ((millis() - lastDebounceTime3) > debounceDelay)
    {
      increase1State = readingincrease3;
    }
  }


  // debouncing button decrease pulse 1
  {
    readingdecrease1 = digitalRead(decrease1Pin);

    if (readingdecrease1 != lastdecrease1State) 
    {
      lastDebounceTime4 = millis();  
    }
    if ((millis() - lastDebounceTime1) > debounceDelay)
    {
      decrease1State = readingdecrease1;
    }
  }

  // debouncing button decrease pulse 2
  {
    readingdecrease2 = digitalRead(decrease2Pin);

    if (readingdecrease2 != lastdecrease2State) 
    {
      lastDebounceTime5 = millis();  
    }
    if ((millis() - lastDebounceTime2) > debounceDelay)
    {
      decrease1State = readingdecrease2;
    }
  }

  // debouncing button decrease pulse 3
  {
    readingdecrease3 = digitalRead(decrease3Pin);

    if (readingdecrease3 != lastdecrease3State) 
    {
      lastDebounceTime6 = millis();  
    }
    if ((millis() - lastDebounceTime3) > debounceDelay)
    {
      decrease1State = readingdecrease3;
    }
  }



  // increasing pulse 1
  {
    if ((increase1State == HIGH) && (duration1 < upperlimitduration1))
    {
      duration1new = duration1 + interval;
    }
    else {
      duration1new = duration1;
    }
    digitalWrite (duration1, duration1new);
  }


  // increasing pulse 2
  {
    if ((increase2State == HIGH) && (duration1 < upperlimitduration2))
    {
      duration2new = duration2 + interval;
    }
    else {
      duration2new = duration2;
    }
    digitalWrite (duration2, duration2new);
  }


  // increasing pulse 3
  {
    if ((increase3State == HIGH) && (duration1 < upperlimitduration3))
    {
      duration3new = duration3 + interval;
    }
    else {
      duration3new = duration3;
    }
    digitalWrite (duration3, duration3new);
  }


  // decreasing pulse 1
  {
    if ((decrease1State == HIGH) && (duration1 > lowerlimitduration1))
    {
      duration1new = duration1 + interval;
    }
    else {
      duration1new = duration1;
    }
    digitalWrite (duration1, duration1new);
  }


  // decreasing pulse 2
  {
    if ((decrease2State == HIGH) && (duration1 > lowerlimitduration2))
    {
      duration2new = duration2 + interval;
    }
    else {
      duration2new = duration2;
    }
    digitalWrite (duration2, duration2new);
  }

  // decreasing pulse 3
  {
    if ((decrease3State == HIGH) && (duration3 > lowerlimitduration3))
    {
      duration3new = duration3 + interval;
    }
    else {
      duration3new = duration3;
    }
    digitalWrite (duration3, duration3new);
  }

  {
    gotoXY(1,1);
    LcdString("P1:");
    gotoXY(30,1);
    char buffer [33];
    itoa (p1,buffer,10);
    LcdString(buffer);
    gotoXY(57,1);
    LcdString(" ms");

    gotoXY(1,3);
    LcdString("Dl:");
    gotoXY(30,3);
    char buffer1 [33];
    itoa (d1,buffer1,10);
    LcdString(buffer1);
    gotoXY(65,3);
    LcdString("ms"); 

    gotoXY(1,5);
    LcdString("P2:");
    gotoXY(30,5);
    char buffer2 [33];
    itoa (p2,buffer2,10);
    LcdString(buffer2);
    gotoXY(65,5);
    LcdString("ms"); 
  }

}

Ich habe einen Taster und einen 8k8 Widerstand in Reihe zwischen D4 und 5V.

Wenn ich den Taster drücke, passiert nichts. Habe ich das mit dem PullUp-Widerstand falsch verstanden?

Vermutlich:
Der Pin an dem du den Schalterzustand liest, muss immer mit irgendwas verbunden sein.
Bei “Pullup” über diesen Widerstand mit 5V wenn offen, oder mit GND wenn geschlossen.

5V — 8k8 —±-- Schalter — GND
|
V
Pin

Ein Taster hat 4 Beinchen, aber eigentlich nur 2 Kontakte. “Diagonal ist immer richtig”.

Blödere Fehler fallen mir jetzt keine mehr ein.

Ok, so hatte ich das vorher nicht.

Habe es jetzt so gelötet.
Dann muss ich aber das Programm ändern, falls der PIN Low wird, oder?
Jetzt ist er ja immer mit +5V verbunden, oder verstehe ich das fallsch?

Ich hab jetzt beides versucht, mit HIGH zum Schalten und mit LOW zum Schalten.
Hat beides leider nicht am Taster funktioniert :frowning:
Was mache ich denn falsch? Eine Durchgangsprüfung zu allen Pins hab ich gemacht.

Vom Anfang sehe ich, dass du ein Nokia LCD hast:

Passiert denn was (erwartetes) mit

...
void loop() {

gotoXY(0,0);
 if (digitalRead(TasterPin))
  LcdString("HI");
 else
  LcdString("LO");

}

Wenn du einen Durchgangsprüfer hast, kannst du sicher auch die Spannung am TasterPin messen.

Der Taster funktioniert.
Das habe ich ausprobiert.

Mit Serial Print bekomme ich ihn auch als high oder low ausgelesen.
Das Problem muss weiter unten beim Entprellen oder beim Ändern der Variable liegen.

Ich habe alles so geändert, dass high Normalzustand ist. Hat das irgendwelche Vor- oder Nachteile?

    // increasing pulse 1
    {
      if ((increase1State == LOW) && (duration1 < upperlimitduration1))
      {
        duration1new = duration1 + interval;
      }
      else {
        duration1new = duration1;
      }
      digitalWrite (duration1, duration1new);
    }

oder drüber beim Entprellen

 // debouncing button increase pulse 1
    {
      readingincrease1 = digitalRead(increase1Pin);

      if (readingincrease1 != lastincrease1State) 
      {
        lastDebounceTime1 = millis();  
      }
      if ((millis() - lastDebounceTime1) > debounceDelay)
      {
        increase1State = readingincrease1;
      }
    }

ist das mit dem “last” vorne dran eigentlich dann immer eine besondere Art von Variable oder könnte ich die nennen, wie ich will?