Sketch zur Servo Ansteuerung hängt sich auf

So habe nun mal alles auf einen Mega hochgeladen und das Display startet und über das Poti lässt sich ein Wert auf dem Display von 0-100% einstellen. Das Servo am PWM Ausgang 9 macht allerdings keinen Muchs und nach ca. 10 Sec hängt sich das ganze auf und das Display friert in der Letzten Position ein.

Offensichtlich ist was noch nicht richtig.

Der Code, den ich gepostet habe, braucht keine Library. Im Gengenteil die würde eher stören. Also diese Zeile:

#include <Servo_Hardware_PWM.h>

muss wieder raus.
Rein zum Testen von Poti und Servo ist der Code auch so wie er im Post #38 steht lauffähig. Einfach in ein neues leeres IDE Fenster kopieren, und auf den Nano laden. Dann sollte sich das Servo mit dem Poti verstellen lassen.

P.S.

wortmann30:
So habe nun mal alles auf einen Mega hochgeladen ... Das Servo am PWM Ausgang 9 macht allerdings keinen Muchs

Das kann auch nicht funktionieren, da auf dem Mega die Zurdnung der Pins zu den Timer-PWM Ausgängen anders ist als beim Nano.

So nun habe ich das mal getestet, nur das einfache Sketch hat funktioniert.

Dann bin ich hergegangen und habe das mal mit meinem Sketch versucht zu vereinigen und das ist dabei raus gekommen.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>
 

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

int potpin = A7;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int val1;   // variable to scale Servo rotation to %

// Intiieren des Timer 1 für Servo-Impulse an Pin 9
void initServo() {
    TCCR1A = _BV(WGM11); /* Fast PWM, ICR1 is top */
    TCCR1B = _BV(WGM13) | _BV(WGM12) /* Fast PWM, ICR1 is top */
              | _BV(CS11) ; // div 8 clock prescaler ( 0,5µs per tic )
    OCR1A = 3000;           // initiale Pulsbreite 1,5ms
    ICR1 = 40000;  // 20ms period
    TCCR1A = TCCR1A & ~_BV(COM1A0) | _BV(COM1A1);   // Output to pin 9 ( OCRA )
}
// Pulsbreite einstellen ( pos in µs )
void servoWrite(int pos) {
  OCR1A = pos*2;
}

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


void setup() {
  pinMode( 9, OUTPUT );
  initServo();
  
  //SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    for (;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
}


void loop() {
  // analogReference(EXTERNAL);     // <<<---- nicht in loop
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 550, 1500);     // scale it to use it with the servo (value between 0 and 180)
  servoWrite(val);                      // sets the servo position according to the scaled value
  display.setCursor(0, 25);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.clearDisplay();
  display.print("Absaugung oben ");
  val1 = map(val, 550, 1500, 0, 100);
  display.print(val1); display.print("%");

  display.display();
  delay(15);
}

Und ich muss sagen auch das funktioniert und die Servos sind nicht mehr ganz so nervös, also schient mir das eine Verbesserung zu sein.
Jetzt muss ich noch das dritte Programm auf dem Arduino anpassen das zwei Servos und einen weiteren Eingang steuert.
Das werde ich probieren und wenn was nicht klappt werde ich mich gerne wieder melden.

Vielen dank mal soweit!

wortmann30:
und die Servos sind nicht mehr ganz so nervös, also schient mir das eine Verbesserung zu sein.

Eigentlich sollten die Servos da ganz still stehen, denn der per Timer erzeugte Impuls ist absolut stabil. Oder müssen die gegen einen größeren Widerstand 'ankämpfen'? Ansonsten könnte noch dein Poti schlecht sein und damit die Spannung am Analogeingang schwanken, oder deine Versorgung ist nicht stabil.

wortmann30:
das zwei Servos und einen weiteren Eingang steuert.

Zwei Servos gingen mit der Methode auch noch. Allerdings muss das 2. Servo dann zwingend an Pin 10 angeschlossen werden, und man müsste die Funktionen ein wenig erweitern.

Edit: Du könntest mal versuchsweise bei demservoWrite(val);einen festen Wert eintragen, z.B.servoWrite(1000);Wenn dann das Servo ruhiger steht, liegt es an deiner Spannung am analogen Eingang.

So ich bin schon wieder da :astonished:

Die Servos müssen eigentlich gegen keinen Widerstand kämpfen.

Zum erweitern also habe mich wirklich bemüht es zu verstehen... dabei bliebs leider...

Also das ist das Ursprungs Sketch das jit dem beiden Servos und einer Eingangs Überwachung:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Servo.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2;

byte ok_pin =3;
byte alarm_pin = 4;

long millis_new;
long millis_old;

Servo myservo;  // create servo object to control a servo

Servo myservo2;  // create servo object to control a servo


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

int potpin = A7;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int Sollwert;   // Variable für den Servo im Bereich 800 bis 2000µs
int val1;
int potpin2 = A6;  // analog pin used to connect the potentiometer
int val2;    // variable to read the value from the analog pin
int Sollwert2;   // Variable für den Servo im Bereich 800 bis 2000µs
int val12;

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

void setup() {
  //Serial.begin(9600);
  //  Serial.println(F("Start"));

  millis_old=0;
  millis_new=0;

  pinMode(ok_pin,OUTPUT);
  pinMode(alarm_pin,OUTPUT);
  // digitalWrite(ok_pin,HIGH);
  digitalWrite(alarm_pin,LOW);

  
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);


  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo.writeMicroseconds(1500);      // PPM Signal zum Servo (Mittelstellung)
  
  myservo2.attach(8);  // attaches the servo on pin 9 to the servo object
  myservo2.writeMicroseconds(1500);      // PPM Signal zum Servo (Mittelstellung) 
  
  //SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    //Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(10, 10, SSD1306_WHITE);

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
}

void loop() {

   // Enable the interrupt
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);


  // put your main code here, to run repeatedly:
  analogReference(EXTERNAL);
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  Sollwert = map(val, 0, 1023, 500, 2500);     // scale it to use it with the servo (value between 0 and 180)
  myservo.writeMicroseconds(Sollwert);                  // sets the servo position according to the scaled value
  display.setCursor(10, 20);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.clearDisplay();
  display.print("MIN ");
//  display.setCursor(0, 36);     // Start at top-left corner
  
  val1 = map(val, 0, 1023, 0, 100);
  display.print(val1); display.print("%");

  

    // put your main code here, to run repeatedly:
  analogReference(EXTERNAL);
  val2 = analogRead(potpin2);            // reads the value of the potentiometer (value between 0 and 1023)
  Sollwert2 = map(val2, 0, 1023, 500, 2500);     // scale it to use it with the servo (value between 0 and 180)
  myservo2.writeMicroseconds(Sollwert2);                  // sets the servo position according to the scaled value
  display.setCursor(10, 50);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.print("MAX ");
//  display.setCursor(0, 36);     // Start at top-left corner
  
  val12 = map(val2, 0, 1023, 0, 100);
  display.print(val12); display.print("%");

  display.display();
  delay(15);  
  }


  /*
Insterrupt Service Routine
 */
void pulseCounter()
{
  millis_new=millis();
  if(millis_new-millis_old>30)
  {
    digitalWrite(ok_pin,LOW);
    digitalWrite(alarm_pin,HIGH);
  }
  else
  {
    digitalWrite(ok_pin,HIGH);
    digitalWrite(alarm_pin,LOW);
  }
  
  millis_old=millis();
}

Fortsetzung folgt:

Dann habe ich versucht es zu bereinigen und um zu stellen und es sieht so aus:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2;

byte ok_pin =3;
byte alarm_pin = 4;

long millis_new;
long millis_old;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

int potpin = A7;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int Sollwert;   // Variable für den Servo im Bereich 800 bis 2000µs
int val1;
int potpin2 = A6;  // analog pin used to connect the potentiometer
int val2;    // variable to read the value from the analog pin
int Sollwert2;   // Variable für den Servo im Bereich 800 bis 2000µs
int val12;

// Intiieren des Timer 1 für Servo-Impulse an Pin 9
void initServo1() {
    TCCR1A = _BV(WGM11); /* Fast PWM, ICR1 is top */
    TCCR1B = _BV(WGM13) | _BV(WGM12) /* Fast PWM, ICR1 is top */
              | _BV(CS11) ; // div 8 clock prescaler ( 0,5µs per tic )
    OCR1A = 3000;           // initiale Pulsbreite 1,5ms
    ICR1 = 40000;  // 20ms period
    TCCR1A = TCCR1A & ~_BV(COM1A0) | _BV(COM1A1);   // Output to pin 9 ( OCRA )
}
// Pulsbreite einstellen ( pos in µs )
void servo1Write(int pos) {
  OCR1A = pos*2;
}
// Intiieren des Timer 2 für Servo-Impulse an Pin 8
void initServo2() {
    TCCR1A = _BV(WGM11); /* Fast PWM, ICR1 is top */
    TCCR1B = _BV(WGM13) | _BV(WGM12) /* Fast PWM, ICR1 is top */
              | _BV(CS11) ; // div 8 clock prescaler ( 0,5µs per tic )
    OCR1A = 3000;           // initiale Pulsbreite 1,5ms
    ICR1 = 40000;  // 20ms period
    TCCR1A = TCCR1A & ~_BV(COM1A0) | _BV(COM1A1);   // Output to pin 9 ( OCRA )
}
// Pulsbreite einstellen ( pos in µs )
void servo2Write(int pos) {
  OCR1A = pos*2;
}

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {

  millis_old=0;
  millis_new=0;

  pinMode(ok_pin,OUTPUT);
  pinMode(alarm_pin,OUTPUT);
  // digitalWrite(ok_pin,HIGH);
  digitalWrite(alarm_pin,LOW);

  
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);


  pinMode( 9, OUTPUT );
  initServo1(); 
  
  pinMode( 8, OUTPUT );
  initServo2();
  
  //SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    //Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
    display.clearDisplay();

  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
}

void loop() {

   // Enable the interrupt
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);


  // put your main code here, to run repeatedly:
  analogReference(EXTERNAL);
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  Sollwert = map(val, 0, 1023, 500, 2500);     // scale it to use it with the servo (value between 0 and 180)
   servo1Write(val);                      // sets the servo position according to the scaled value
  display.setCursor(10, 20);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.clearDisplay();
  display.print("MIN ");
//  display.setCursor(0, 36);     // Start at top-left corner
  
  val1 = map(val, 0, 1023, 0, 100);
  display.print(val1); display.print("%");

  

    // put your main code here, to run repeatedly:
  analogReference(EXTERNAL);
  val2 = analogRead(potpin2);            // reads the value of the potentiometer (value between 0 and 1023)
  Sollwert2 = map(val2, 0, 1023, 500, 2500);     // scale it to use it with the servo (value between 0 and 180)
   servo2Write(val);                      // sets the servo position according to the scaled value
  display.setCursor(10, 50);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.print("MAX ");
//  display.setCursor(0, 36);     // Start at top-left corner
  
  val12 = map(val2, 0, 1023, 0, 100);
  display.print(val12); display.print("%");

  display.display();
  delay(15);  
  }


  /*
Insterrupt Service Routine
 */
void pulseCounter()
{
  millis_new=millis();
  if(millis_new-millis_old>30)
  {
    digitalWrite(ok_pin,LOW);
    digitalWrite(alarm_pin,HIGH);
  }
  else
  {
    digitalWrite(ok_pin,HIGH);
    digitalWrite(alarm_pin,LOW);
  }
  
  millis_old=millis();
}

Was nun funktioniert ist das Display und die Verstellung der beiden Potis.
Das erste Servo na Pin 9 funktioniert auch aber das Servo an Pin 8 geht gar nicht.
Ich habe auch irgendwie gar nicht verstanden wo ich die Zuordnung der Servos auf die Ausgänge mache.
Ich nehme an das wird hier eingestellt:

    TCCR1A = TCCR1A & ~_BV(COM1A0) | _BV(COM1A1);   // Output to pin 9 ( OCRA )

Aber was muss ich da definieren? Ich habe es mal auf D10 umgehängt es war vorher auf D8.

Weiter sind die Servos Spezial servos die nicht 180° drehen sondern 300°.
Mit dem alten Sketch haben diese auch 300° gedreht aber mit dem angepassten Sketch nicht mehr.
Wo ist da die Definition?

Nein, so funktioniert das auch nicht. Der Timer 1 ist in der Lage 2 PWM-Signale ( für deine 2 Servos ) zu erzeugen. Da muss man dann die initiierung etwas erweitern aber nicht komplett 2mal schreiben. Das bringt nichts. Die PWM-Ausgänge sind aber prozessorintern fest verdrahtet, deshalb geht das nur an Pin 9 und 10.
Ich werde meinen kleinen Beispielsketch mal auf 2 Servos erweitern, kann aber ein wenig dauern, komme im Moment gerade nicht dazu.

Zum Drehbereich:
Wenn Du deinen Analogwert auf den Sollwert für das Poti mappst, musst Du dann auch diesen Wert an den TImer übergeben:

 Sollwert = map(val, 0, 1023, 500, 2500);     // scale it to use it with the servo (value between 0 and 180)
   servo1Write(Sollwert);                      // sets the servo position according to the scaled value >>Sollwert<<

P.S. Der Sketch, auf die Schnelle geändert - kann es aber gerade nicht testen. Probiers einfach aus:

const int pot1pin = A7;  // analog pin used to connect the potentiometer
const int pot2pin = A6;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int Sollwert; 

// Intiieren des Timer 1 für Servo-Impulse an Pin 9 und 10
void initServo() {
    TIMSK1 = 0;         // keine Interrupts 
    TCCR1A = _BV(WGM11); /* Fast PWM, ICR1 is top */
    TCCR1B = _BV(WGM13) | _BV(WGM12) /* Fast PWM, ICR1 is top */
              | _BV(CS11) ; // div 8 clock prescaler ( 0,5µs per tic )
    OCR1A = 3000;           // initiale Pulsbreite 1,5ms
    OCR1B = 3000;           // initiale Pulsbreite 1,5ms
    ICR1 = 40000;  // 20ms period
    TCCR1A = TCCR1A & ~_BV(COM1A0) | _BV(COM1A1);   // Output to pin 9 ( OCRA )
    TCCR1A = TCCR1A & ~_BV(COM1B0) | _BV(COM1B1);   // Output to pin 10 ( OCRB )
}

// Pulsbreite einstellen ( pos in µs )
void servo1Write(int pos) {
  OCR1A = pos*2;
}

void servo2Write(int pos) {
  OCR1B = pos*2;
}

void setup() {
  pinMode( 9, OUTPUT );
  pinMode( 10, OUTPUT );
  initServo();
}

void loop () {
  val = analogRead(pot1pin);             // reads the value of the potentiometer (value between 0 and 1023)
  Sollwert = map(val, 0, 1023, 550, 1500);  // scale it to use it with the servo (value between 1000 and 2000 µs)
  servo1Write(Sollwert);                      // sets the servo position according to the scaled value

  val = analogRead(pot2pin);             // reads the value of the potentiometer (value between 0 and 1023)
  Sollwert = map(val, 0, 1023, 550, 2500);  // scale it to use it with the servo (value between 1000 and 2000 µs)
  servo2Write(Sollwert);                      // sets the servo position according to the scaled value
}

wortmann30:
Ich habe auch irgendwie gar nicht verstanden wo ich die Zuordnung der Servos auf die Ausgänge mache.

Dazu wirst Du das Datenblatt des ATMega386P bemühen müssen :wink: .
Diese ganzen groß geschriebenen 'Variablen', die da beschrieben werden, sind direkte HW-Register des Timer 1. Die Zusammenhänge kann man nur mit Hilfe des Datenblatts verstehen. Wenn Du da nicht tiefer einsteigen willst, dann betrachte die 3 Funktionen als 'black box' - so wie eine Library auch.

Black Box ist ok für mich :slight_smile:

Ich habe versucht das einzubauen, es funktioniert fast.
Das erste Servo dreht jetzt die 300°
Aber irgendwas will nicht beim Servo 2. Die Anzeige geht aber das Servo bewegt sich nicht.
Das erste ist auf D9 und das zweite auf D10 wie du geschrieben hats.
Was hab ich nur übersehen und falsch gemacht?

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2;

byte ok_pin =3;
byte alarm_pin = 4;

long millis_new;
long millis_old;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

int pot1pin = A7;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int Sollwert;   // Variable für den Servo im Bereich 800 bis 2000µs
int val1;
int pot2pin2 = A6;  // analog pin used to connect the potentiometer
int val2;    // variable to read the value from the analog pin
int Sollwert2;   // Variable für den Servo im Bereich 800 bis 2000µs
int val12;

// Intiieren des Timer 1 für Servo-Impulse an Pin 9 und 10
void initServo() {
    TIMSK1 = 0;         // keine Interrupts
    TCCR1A = _BV(WGM11); /* Fast PWM, ICR1 is top */
    TCCR1B = _BV(WGM13) | _BV(WGM12) /* Fast PWM, ICR1 is top */
              | _BV(CS11) ; // div 8 clock prescaler ( 0,5µs per tic )
    OCR1A = 3000;           // initiale Pulsbreite 1,5ms
    OCR1B = 3000;           // initiale Pulsbreite 1,5ms
    ICR1 = 40000;  // 20ms period
    TCCR1A = TCCR1A & ~_BV(COM1A0) | _BV(COM1A1);   // Output to pin 9 ( OCRA )
    TCCR1A = TCCR1A & ~_BV(COM1B0) | _BV(COM1B1);   // Output to pin 10 ( OCRB )
}

// Pulsbreite einstellen ( pos in µs )
void servo1Write(int pos) {
  OCR1A = pos*2;
}

void servo2Write(int pos) {
  OCR1B = pos*2;
}

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {

  millis_old=0;
  millis_new=0;

  pinMode(ok_pin,OUTPUT);
  pinMode(alarm_pin,OUTPUT);
  // digitalWrite(ok_pin,HIGH);
  digitalWrite(alarm_pin,LOW);

  
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);


  pinMode( 9, OUTPUT );
  pinMode( 10, OUTPUT );
  initServo();
  
  //SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    //Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
    display.clearDisplay();

  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
}

void loop() {

   // Enable the interrupt
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);


  // put your main code here, to run repeatedly:
  analogReference(EXTERNAL);
   val = analogRead(pot1pin);            // reads the value of the potentiometer (value between 0 and 1023)
  Sollwert = map(val, 0, 1023, 500, 2500);     // scale it to use it with the servo (value between 0 and 180)
  servo1Write(Sollwert);                       // sets the servo position according to the scaled value
  display.setCursor(10, 20);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.clearDisplay();
  display.print("MIN ");
//  display.setCursor(0, 36);     // Start at top-left corner
  
  val1 = map(val, 0, 1023, 0, 100);
  display.print(val1); display.print("%");

  

    // put your main code here, to run repeatedly:
  analogReference(EXTERNAL);
  val2 = analogRead(pot2pin2);            // reads the value of the potentiometer (value between 0 and 1023)
  Sollwert2 = map(val2, 0, 1023, 500, 2500);     // scale it to use it with the servo (value between 0 and 180)
 servo2Write(Sollwert);                        // sets the servo position according to the scaled value
  display.setCursor(10, 50);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.print("MAX ");
//  display.setCursor(0, 36);     // Start at top-left corner
  
  val12 = map(val2, 0, 1023, 0, 100);
  display.print(val12); display.print("%");

  display.display();
  delay(15);  
  }


  /*
Insterrupt Service Routine
 */
void pulseCounter()
{
  millis_new=millis();
  if(millis_new-millis_old>30)
  {
    digitalWrite(ok_pin,LOW);
    digitalWrite(alarm_pin,HIGH);
  }
  else
  {
    digitalWrite(ok_pin,HIGH);
    digitalWrite(alarm_pin,LOW);
  }
  
  millis_old=millis();
}

Hier

  Sollwert2 = map(val2, 0, 1023, 500, 2500);     // scale it to use it with the servo (value between 0 and 180)
 servo2Write(Sollwert);                        // sets the servo position according to the scaled value

hast Du vergessen, den Sollwert für Servo2 auf 'Sollwert2' zu ändern. Allerdings hätte ich dann erwartet, dass sich das 2. Servo parallel mit dem ersten dreht. Vielleicht ist noch ein Bug drin. Muss mal schauen, dass ich dazu komme es auch zu testen.

P.S. hast Du es mal mit den 'nackten' Sketch aus #46 versucht?

Hi

ja mit dem Sketch von 46 gehen beide.

Jetzt habe ich das angepasst und es funktioniert.

Die Servos zappeln aber immer noch ein wenig, zumindest weniger wie zuvor aber noch nicht 100% still.

Welche Leitungen bringen denn Störsignale, und wie könnte ich diese bekämpfen?

wortmann30:
Die Servos zappeln aber immer noch ein wenig, zumindest weniger wie zuvor aber noch nicht 100% still.

Hast Du denn mal versucht, statt des 'Sollwert' einen konstanten Wert an das Servo zu übergeben? So könnte man feststellen, ob es am Analogeingang liegt.

Also es muss schon an den Kabeln liegen denn machen ich einen Versuchsaufbau zappelt nichts... Mist

In einem Laser laufen natürlich viele Leitungen aneinander, von Niederspannung 5V, 24V, 36V, 220VAC und 26kV DC für die Röhre. Energie für Schrittmotoren, Endschalter und sowas. Obwohl während die Servos zappeln der Laser einfach nur im Standby ist und kein Schrittmotor verfährt oder so und die Hochspannung ist derzeit gar nicht eingeschaltet.

Kann ich da nicht irgendwie Kondensatoren an die Ein und Ausgänge hängen um die Störungen raus zu filtern?
Sorry hier spricht der der kaum Ahnung von Elektronik und solchen Störungsdingen hat, bin eher der Grob Stromer.

Update

Ich habe weiter gesucht.

Die Situation ist wie folgt, die beiden 300° Servos werden durch +6V und GND gemeinsam versorgt.
Die beiden parallel geschalteten "Absaugung unten" Servos sind mit Y Kabel dran, das "Absaugung Oben" Servo (nur eines) teile sich die Spannungsversorgung mit dem "Absaugung unten" aber nur mit dem entfernteren (längerem Kabel).

Die beiden Servos, einmal "Absaugung unten" und "Absaugung Oben", die sich die Spannung Versorgung teilen, liefen mit den Kabeln für Endschaltern und 2 Step Motoren in einem 15mm Rohr zusammen durch. Jetzt habe ich diese aus Verzweiflung mal rausgezogen und da wurden die Störungen besser.

Zusätzlich wenn beide Servos an der an der gemeinsamen Leitung für 5V liegen sind sie wiederum störanfälliger wenn ich eine Zweite + - Leitung ziehe wird es besser und kommt fast in den beriech des akzeptablen.

Work arround
Ich werde die Servoleitugen entfernt der anderen Leitung neu verlegen und jeder bekommt seine eigene Powerzuleitung.

Aber vielleicht kann ich noch etwas mehr entstören...

Hat keiner ne Idee wie ich die Eingänge entstören kann, also nicht die PWM Ausgänge aber die Digitalen Eingänge z.b. mit einem kleinen Kondensator gegen Masse?
Hat da jemand Erfahungen?

Ich habe auch die analogen Eingänge in Verdacht, an denen die Potis hängen. Störungen, die dort einstreuen wirken sich direkt auf die Position der Servos aus. Deshalb hatte ich ja auch vorgeschlagen, die Servos mal mit festen Werten anzusteuerun, um diesen Störeinfluß verifizieren zu könen. Hast Du das mal gemacht?
Wie lang sind den die Kabel vom Poti zum Arduino, und mit welcher Spannung werden die Potis versorgt?

Also

ich habe es mal versucht mit einem Spannungsteiler den einen (nie alle gleichzeitig) mit einer konstanten Spannung zu versorgen. Das Zappeln ist vielleicht etwas besser geworden.

Die Leitungen sind auch ca. 90cm lang laufen aber alle Ausnahmslos nur an Niederspannung 5, 24VDC vorbei, derzeit im Strang mit I2C bus und einem Temperatur Sensor, ich denke es ist ein PT100, die anderen Signale sind mit LED oder Schaltern verbunden also nichts was eigentlich groß ein Störfeld bilden könnte...

Ich habe gesehen das z.B. HIER in Beitrag Nr 8 ein Kondensator am Poti hängt wie groß sollte denn so einer sein, ich habe einfach mal was au der Kiste genommen, da seht 332 drauf ich glaube das sind 3,3pf oder liege ich da falsch. Reicht das oder solle da ein anderer Wert rein?

Was haltet ihr von sowas bei jedem Ein- / Ausgang einen das Kabel 2-3 mal durchwickeln?

Würde das reichen oder muss da jeweils die Betriebsspannung und Masse auch nochmal durch?

wortmann30:
ich habe es mal versucht mit einem Spannungsteiler den einen (nie alle gleichzeitig) mit einer konstanten Spannung zu versorgen. Das Zappeln ist vielleicht etwas besser geworden.

Um EInflüsse des Analogeingangs sicher auszuschließen, müsstest Du versuchsweise im Sketch einen konstanten Wert übergeben. Z.B.::

  servo1Write(1000);                       // sets the servo position according to the scaled value

Wenn es dann noch zappelt, kannst Du sicher sein, dass das nicht am Analogeingang liegt und musst die Ursache woanders suchen.

wortmann30:
Die Leitungen sind auch ca. 90cm lang laufen aber alle Ausnahmslos nur an Niederspannung 5, 24VDC vorbei, derzeit im Strang mit I2C bus und einem Temperatur Sensor, ich denke es ist ein PT100, die anderen Signale sind mit LED oder Schaltern verbunden also nichts was eigentlich groß ein Störfeld bilden könnte...

90cm sind schon recht lang, vor allem wenn die Leitung recht hochohmig ist. Welchen Wert haben denn deine Potis, und macht es einen Unterschied, ob sie in der Mitte oder am Anschlag stehen?

wortmann30:
Ich habe gesehen das z.B. HIER in Beitrag Nr 8 ein Kondensator am Poti hängt wie groß sollte denn so einer sein, ich habe einfach mal was au der Kiste genommen, da seht 332 drauf ich glaube das sind 3,3pf oder liege ich da falsch. Reicht das oder solle da ein anderer Wert rein?

das dürften eher 3,3nF sein ( 3300pf, die 3. Ziffer sind die Anzahl der Nullen ). Der Wert dürfte aber gern deutlich größer sein. Du willst ja keine hohen Frequenzen einlesen :wink: . Und ich würde den Kondensator eher direkt am Analogeingang anschließen und nicht am Poti.
Du solltest mir der obigen Sketchänderung aber erstmal prüfen, wie hoch der Einfluß von Störungen am Analogeingang überhaupt ist.

Also mit

  servo1Write(1000);                       // sets the servo position according to the scaled value

Stehen die Servos sehr Stabil, ich glaube ich / Wir müssen weiter in diese Richtung gehen.

Als Leitung habe ich ein Flachbandkabel mit Ader Querschnitt von 0,08mm² ich dachte da läuft ja kaum Strom drüber bei 500k Potis. soll ich auf einzelne Litzen mit 0,14mm² gehen, das habe ich da? Auf 0,5mm² ist mir fast zu groß das ist die nächste Größe die ich da haben.

Und welche Größe von Kondensator würdest du raten?