Liebe Forengemeinde,
Für unsere ferngesteuerten LEGO® Autos habe ich eine bidirektionale Motorsteuerung mit einem ATtiny45 und dem Motortreiber RZ7886 entwickelt. Der Tiny45 soll die Pulsbreite vom Empfänger auswerten und ein PWM Signal – je nach Fahrtrichtung und Geschwindigkeit – an den Motortreiber ausgeben.
Die Pulsbreite liegt üblicherweise zwischen 1000 und 2000 µs, kann aber je nach Fernbedienung leicht darüber oder darunter liegen.
Aus irgendeinem Grund, der sich mir nicht erschließt fängt der Motor bei Erreichen des max. Wertes für ‚Rückwärts‘ - im Sketch die 1050 - an zu Stottern. Dieses Stottern hört auf, wenn man den Hebel der Fernbedienung ein kleines Stück zurück oder noch ein Stück weiter bewegt.
Auf einem ATmega328pb funktioniert der Sketch einwandfrei.
Habt ihr eine Idee woran das liegt, dass der Tiny45 das nicht so macht?
/*
Using ATtiny45 @8MHz on AUBR® micro board
Hyperbolic Drive Control and Channel 3 for switching Lights
*/
#include <PinChangeInterrupt.h>
#define DRIVE_OUT1 0 // 9
#define DRIVE_OUT2 1 // 10
#define DRIVE_IN 2 // 22 PCINT#
#define LIGHTS_IN 4
#define LIGHTS_OUT 3
unsigned int driveOutput = 0;
unsigned int driveMap = 0;
unsigned int lightsInput = 0;
bool lightsOn = false;
volatile unsigned int pulseDuration = 0;
volatile unsigned int risingTime = 0;
//************************************************************
void setup() {
pinMode( DRIVE_OUT2, OUTPUT );
pinMode( DRIVE_OUT1, OUTPUT );
pinMode( LIGHTS_OUT, OUTPUT );
attachPCINT ( DRIVE_IN, rising, RISING );
}
//************************************************************
void loop() {
lightsInput = pulseIn( LIGHTS_IN, HIGH );
if ( lightsInput > 1400 ) PORTB |= ( 1 << 3 );
if ( lightsInput < 1400 ) PORTB &= ~ ( 1 << 3 );
/*
if ( lightsInput > 1400 && !lightsOn ) {
//digitalWrite( LIGHTS_OUT, HIGH );
PORTB |= ( 1 << 3 );
lightsOn = true;
}
if ( lightsInput < 1400 && lightsOn ) {
// digitalWrite( LIGHTS_OUT, LOW );
PORTB &= ~( 1 << 3 );
lightsOn = false;
}
*/
}
//************************************************************
//************************************************************
void rising() {
attachPCINT ( DRIVE_IN, falling, FALLING );
risingTime = micros();
}
void falling() {
attachPCINT ( DRIVE_IN, rising, RISING );
pulseDuration = micros() - risingTime;
drive( pulseDuration );
}
void drive( unsigned int driveInput ) {
if ( driveInput > 2500 || driveInput < 500 ) driveInput = 1500;
//constrain ( driveInput , 900, 2000 );
// vorwärts
if ( driveInput > 1500 ) {
driveMap = map( driveInput, 1500, 1950, 0, 255 );
if ( driveMap > 255 ) driveMap = 255;
driveOutput = sq( driveMap ) / 255;
digitalWrite( DRIVE_OUT1, LOW );
analogWrite ( DRIVE_OUT2, driveOutput );
}
// rückwärts
else if (driveInput < 1500) {
driveMap = map( driveInput, 1500, 1050, 0, 255 );
if ( driveMap > 255 ) driveMap = 255;
driveOutput = sq( driveMap ) / 255;
digitalWrite( DRIVE_OUT2, LOW );
analogWrite ( DRIVE_OUT1, driveOutput );
}
else {
digitalWrite( DRIVE_OUT1, LOW );
digitalWrite( DRIVE_OUT2, LOW );
}
}
//************************************************************
//************************************************************




