Seite 1 von 1

#1 Hat Switch Nachrüstung für Pultsender

Verfasst: 25.03.2011 09:56:02
von acanthurus
Hallo, Freunde.
Demnächst möchte ich nach fast 10 Jahren Abstinenz den Wiedereinstieg ins FPV-Fliegen machen.
Dafür wird jetzt der Sender entsprechend hochgerüstet, und ich möchte euch hier meinen HatSwitch vorstellen, den ich derzeit Stück für Stück entwickle... es handelt sich also um die Dokumentation eines laufenden Projektes, nicht um eine direkte Nachbauanleitung.

ZWECK:
Kopfneigetechnik zum nachführen der FPV-Kamera ist nichts für mich, das habe ich bei früheren gelegenheiten schon gemerkt. Wie aber möglichst ergonomisch eine Pan-Tilt-Steuerung integrieren? Wie machen das die Gamer? Früher war der "Cooliehat" bzw. Hat Switch die Standardmethode dafür. Ich verwende sie selbst bei X-Plane am Sim, und komme damit gut klar. Warum also nicht auch für den Sender? genau DARUM geht es hier.
Prinzipiell will ich damit einfach zwei Geberkanäle der Anlage steuern. Das könnten also auch Klappen, Fahrwerk oder sonstwas sein. Die Motivation entstand aber aus dem FPV.

AUSGANGSMATERIAL
Ich fliege seit über eineinhalb Jahrzehnten einen Pultsender, die MPX MC3030. Das ganze Verfahren bietet sich vorwiegend für Zeigefinger/Daumen-Pultsenderpiloten an. Ob eine Adaption für Daumen-Handsender sinnvoll ist wage ich zu bezweifeln. Das ist also nur was für die altmodischen.
Einen geeigneten miniaturisierten HatSwitch habe ich bereits gefunden.
Dieser Switch hat vier Schaltrichtungen für Pan/Tilt rechts/links/hoch/runter sowie einen zentralen Taster. Dieser soll später mal zur schnellen Zentrierung der Blickrichtung dienen, damit man nicht aufwendig schrittweise wieder in die vermeintliche Mitte "tastern" muss sondern nur einmal kurz "Geradeaus" befehlen kann.

STICK-AUFBAU
Ich fliege Mode 1 und verwende den HatSwitch auf dem linken Knüppel (da wo Nick/Gier liegt, bzw. Höhe und Seite, denn ich will zunächst nur Starrflügler-FPV und Koax-FPV machen). Mit einem Holzrohling wurde zuächst mal eine möglichst ergonomische Einbaulage rausgemessen - die Hatswitch-Ebene soll etwa 30° nach hinten geneigt werden. Der Stick hatte zuvor einen Geberkanaltaster oben drauf (Photoauslösung, Schleppkupplung etc.). Damit diese Möglichkeit erhalten bleibt, habe ich als erstes einen kleinen SMD-Taster (diesen hier) liegend in den Stick eingebaut.
Die Verdrahtung ist knifflig herzustellen. Da ich keine Codierungsverfahren verwenden will/kann, muss ich insgesamt 8 Adern durch den Stick fädeln. Ich verwende feinen Kupferlackdraht, das hat sich an anderer Stelle schon bewährt und in den Abmaßen unschlagbar. Das erste Drahtbündel ist zweipolig und "bedient" den Geberkanaltaster. Ein 6-poliges Bündel wurde verdrillt und an den HatSwitch angelötet. Das ist 1x Masse, 4x Tastausgang für die Richtungen und 1x für den im Hatswitch integrierten Mitte-Taster.
Also am Stick den Deckel entfernt, schräg gefeilt, dann ein kleines Loch für den Stempel des Geberkanaltasters gebohrt, diesen verdrahtet und eingesetzt. Dahinter hats noch ein wenig Luft im Stick, weshalb ich dort ein kleines Kunststoffröhrchen gesetzt habe, welches als Kabelführung für den 6-pol. Strang des HatSwitch dient und gleichzeitig den Geberkanaltaster in Position hält. Das Ganze vooorsichtig mit Sekundenkleber gesichert.
Dann wird die Verdrahtung des Hatswitch durchgezogen, und dieser vooorsichtig mit Heißkleber oben am Stick befestigt. Sekundenkleber war mir dafür zu heikel, da dieser leicht in die Mechanik des Schalters geraten könnte.

Soweit dazu, dass ist der aktuelle IST-Stand. Zwar ist das noch ohne Funktion, aber ich habe im Flug schon mal die Erreichbarkeit dieser neuen Bedienelemente getestet - und das ist alles "gefühlsecht" so wie ich mir das gewünscht habe.

Jetzt ist erstmal ne kleine Denkpause angesagt, und demnächst kommt dann das Thema "Anbindung an den Sender".
Kommentare sind ausdrücklich erwünscht.

#2 Re: Hat Switch Nachrüstung für Pultsender

Verfasst: 25.03.2011 10:01:44
von Bran
Coole Idee! Fliege zwar mit Handsender, aber wenn man eh immer die Finger am Knüppel hat, wieso nicht den Schalter dort hin bauen...?
Ich werd weiter verfolgen!

#3 Re: Hat Switch Nachrüstung für Pultsender

Verfasst: 25.03.2011 10:48:28
von acanthurus
Weiter gehts.

Anbindung an den Sender

Geberkanäle der MC3030 arbeiten intern als analoger 0-5V-Eingang, der normalerweise durch Schalter oder Potis zwischen den herausgeführten 0V- und 5V-Rails bedient wird. Also muss auch ich zwei unterschiedliche 0-5V Signale erzeugen.
Das könnte man jetzt einfach mit zwei digitalen Up-Down-Potis machen. Aus verschiedenen Gründen, insbesondere aber wegen meines geplanten "Mitte"-Tasters, habe ich beschlossen das lieber über einen Microcontroller zu machen. Ich nehme (wie immer, da ich da schöne kleine Platinchen vom Lama Lightboard übrig habe) einen attiny26. Im Prinzip tuts aber jeder AVR, der mindestens 5 Port-Eingänge, 2 Port-Ausgänge und zwei single ended A/D-Kanäle hat.
Ich simuliere mit dem Controller einen D/A-Wandler, indem ich vom Portausgang aus über einen Widerstand einen Elko lade und dessen Ladespannung rückwärts wieder über einen A/D-Kanal einlese. Das Ganze läuft in der Endlosschleife: Ist die Ausgangsspannung kleiner als der geforderte Wert, wird der Port kurz auf high geschaltet und läd den Elko. Ist die Spannung zu groß, so schaltet der Port auf Low und entläd den Elko. zwischendurch werden die Tasten abgefragt um die Sollspannungen festzulegen.
Diese D/A-Geschichte funktioniert recht gut (hab ich an anderer Stelle schon öfter so gemacht) und löst theoretisch 10 Bit auf. Da ich recht große Kapazitäten gewählt habe, ist das zeitlich etwas träger als nötig, aber immer noch locker ausreichend schnell für die Aufgabe. Zudem habe ich nicht das Problem der Glättung, welches ich bei einer D/A mittels AVR-interner PWM hätte.
In dieser Komplettschaltung ist das bisher aber unerprobt. Ne erste Codeversion steht grob, muss aber noch aufgebaut un getestet werden bevor es ind ie Anlage wandert.

*edit* Schaltplan aktualisiert

#4 Re: Hat Switch Nachrüstung für Pultsender

Verfasst: 25.03.2011 16:06:20
von Alex K.
Ist ja cool ;) Deine 3030 wird langsam wirklich noch zur Mondlandefähre ;)

Gruß, ALex

#5 Re: Hat Switch Nachrüstung für Pultsender

Verfasst: 26.03.2011 13:53:16
von acanthurus
Yep, die ist wirklich nicht mehr ganz orginooooool ;)

#6 Kleiner Zwischenstand

Verfasst: 22.07.2011 12:55:41
von acanthurus
Soooo, endlich hab ich mal wieder an dieser Sache weitergearbeitet. Die Software funktioniert, löst effektiv vielleicht 8 Bit auf und enthält ein wenig "tast-Expo" - d.h. je länger gedrückt wird, desto schneller schwenkt die Kamera.
Die Restwelligkeit des primitiv-DA-Wandlers beträgt weniger als 10mV, also <0.2% des Signals. In Anbetracht der Tatsache dass außer dem Controller nur ne Handvoll passive Bauteile Verwendung finden (und die einfachen Kameraservos sowieso nicht so genau auflösen) ist das durchaus akzeptabel.
Ein Prototypenmodul auf Lochraster ist zusammengebraten. Dieses Wochenende erfolgt dann hoffentlich endlich der Einbau.

#7 Re: Hat Switch Nachrüstung für Pultsender

Verfasst: 24.07.2011 17:07:14
von acanthurus
So, endlich fertig.

Die Sache funktioniert wunschgemäß.
Hier ein kleines Video, das sagt mehr als 1000 Worte.
RHF Videothek
Direktlink zur RHF-Videothek ok, und zu dämlich, Hatswitch richtig zu schreiben bin ich auch noch... :lol:

Theoretisch kann man damit noch andere Sachen "bedienen", z.B. Kreiselempfindlichkeit, Gasvorwahl, Landeklappen bei Flächenfliegern usw.... also lauter Dinge, für die der Pultflieger dann die Knüppel nicht mehr loslassen muss um zwei weitere Analogkanäle zu bedienen. Dafür wären ggf. leichte Anpassungen in der Software sinnvoll.

#8 Re: Hat Switch Nachrüstung für Pultsender

Verfasst: 16.12.2017 11:34:48
von skysurfer
Hi Andi,

sehe leider erst jetzt deinen Beitrag.

8) 8) 8) 8) 8)
Saugut gemacht.

Hättest Du vielleicht interesse, einen kleinen Workshop dazu zu machen :?:
Ganz speziell für Dummis.
Mich z.B. würde schonmal interessieren, mit welchen Mittel (Controller, Programmieradapter, Software usw.) Du sowas realisierst.
Vielleicht könntest Du auch den Quellcode offenlegen :oops:

#9 Re: Hat Switch Nachrüstung für Pultsender

Verfasst: 16.12.2017 11:56:17
von Stein
Super Idee...

Sollte ein neuer Sender bei dem einen oder anderen anstehen.
Ich habe eine FRSKY Horus, da sind Lagesensoren drin. Wenn man den Sender nach vorne kippt, kann man das Gimbal neigen.
Wenn man den Sender seitlich kippt, kann man das zum Schwenken der Kamera nutzen. Geht auch mit Pultsender. Sieht dann halt lustig aus, wenn man da hin und her wackelt.

#10 Re: Hat Switch Nachrüstung für Pultsender

Verfasst: 16.12.2017 15:04:24
von acanthurus
Hallo, Hans-Peter.

Controller: in meinem Fall ein Attiny 26, wie oben schon geschrieben.

Programmieradapter: Hab aus vergangenen Zeiten ein Atmel STK500 im Einsatz. Ist aber eignetlich egal, alles was irgendwie AVRs toasten kann dürfte gehen.

Quellcode ist kein Geheimnis, nur ist das extremely quickl and very dirty geschrieben.
Ich hab das Ganze auf WinAVR in C geschrieben, es läuft auf einem nackten Atmel controller, ohne das ganze (in diesem Fall völlig unnötige) Arduino-Gedöhns drumrum. Gut möglich dass da noch reichlich Code-Artefakte drin sind, ich hab (wie meistens) einiges weiterverwendet, was schon irgendwo rumlag.

Code: Alles auswählen

// (c) Andreas K. Fischer
//
// Cooliehat twin channel digital potentiometer for MC3030, volatile centered positions (no eeprom usage)
// Code developed by: Andreas Fischer
// Code version: cooliehat_0.1 initiated 
// Code started: 12.7.2010 (as cooliehat_0.1.c) with 3 channels
// Last change:  25.3.2011 (Downgrade to two channels, cooliehat_0.1_2ch.c)
//
// Things done
// - Key and Pin Assignment
// - Port init
// - Initial centering
// - Continuous DAC
// - Keyboard readout
// - Progressive deflection speed
//
// Things to do:
// - Build some hardware! And seriously think about impedance and capacity.
// - A lot of testing
//  
// Things that might be done or not:
// - Maybe move the DAC business into ISR for much better style?
// - Maybe introduce nonvolatile position storage? Maybe not...
// - Status LED or noisemaker
//
// Hardware configuration
// 
// target device: 	Atmel Attiny26 AVR 
// target speed:    	1000000 internal RC Oscillator
// target voltage:	5V
// target compiler: 	avr-gcc (WINAVR Rev. 20050214 or higher)
// 
// Fuse Bits:
// BODLEVEL=0		Brownout detection level 4.0V 
// BODEN=0		Enable brownout detection
// CKSEL=0001; SUT=10	Internal 1MHZ RC Osc, 6cycles+64ms Startup (no need to hurry)
//
// Lock Bits:
// Mode 1		No locks (at least for now)
//
// Pin usage:
// PA0: ADC0 Analog feedback for DAC, input from channel 0, Pin 20
// PA1: ADC1 Analog feedback for DAC, input from channel 1, Pin 19

// PA3: ADC external reference
// PA4: switched Output DAC CH0, PIN14
// PA5: switched Output DAC CH1, PIN13

// PA7: Status LED or speaker (not used yet)
// PB0: Key Input CH0 UP, PIN1
// PB1: Key Input CH0 DOWN, PIN2
// PB2: Key Input CH1 UP, PIN3
// PB3: Key Input CH1 DOWN, PIN4
// PB6: Key Input Center, Pin 9
// PB7: MCU Reset, Pin 10

#ifndef F_CPU
#define F_CPU 1000000   				// RC-OSC running at 1Mhz
#endif
#include <stdint.h>   					// Standard variable type definitions
#include <avr/io.h>     				// input/output definitions
#include <util/delay.h>  				// delay routines for slowing down
// #include <stdlib.h>     				// Standard Library, contains ABS
// #include <math.h>					// Math library for arithmetic operations,
							// Just in case we do something weird to calibration curves later
														
#define sbi(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT))) 	// compatibility with old WINAVR versions
#define cbi(ADDRESS,BIT) ((ADDRESS) &= ~(1<<(BIT)))	// handy macros for "expired" old winavr code
#define outp(VAL,ADRESS) ((ADRESS) = (VAL))
#define inp(VAL) (VAL)

											
#define MINDEFLECT (5)   				// minimum deflection range
#define MAXDEFLECT (1023-MINDEFLECT)   			// maximum deflection range
#define CENTERDEFLECT (512)				// center position
#define TOLERANCE (4)				// allowed tolerance for DAC
#define CH0UPKEY (0)					// Definition of various keys
#define CH0DOWNKEY (1)										
#define CH1UPKEY (2)
#define CH1DOWNKEY (3)
#define CENTERKEY (6)
#define CH0ADC (0)					// Definition of ADC backreading Channels
#define CH1ADC (1)	
#define CH0DAC (4)					// Definition of DAC output pins
#define CH1DAC (5)
#define LEDPIN (7)

#define KEYSPEED (25)   				// initial number of DAC cycles between keyboard processing - determines initial key speed
#define KEYLIMIT (5)					// Final number of DAC cycles between keyboard processing - determines max key speed
#define KEYSTEPS (3)				// number of consecutive key press events before key sampling speed is increased - controls key acceleration

#define DEBOUNCETIME (75)								// debounce timing for keys in milliseconds
#define STARTUPDELAY (250)								// Delaytime after startup for ADC init in milliseconds

// Note: After initialization of ADC sample, CPU idles to wait for ADC complete interrupt.
// This CPU time is in principle available for at least 32 clock cycles worth of code.



uint16_t ADCstep(uint8_t channel)					// Read ADC Channel
{ 									// Return value: sample value 
  uint16_t sample;

  ADCSR = (1<<ADEN) |  (1<<ADPS2);    					// preset frequency prescaler to 16 and activate ADC on Port A
  ADMUX = channel;							// Select ADC channel, Voltage reference external AVCC
  ADCSR |= (1<<ADSC);              					// Initiate sample
  while ( ADCSR & (1<<ADSC));						// wait for sampling to be completed
  sample= ADCW;
  return(sample);
}	



int main(void)
 {
  
   uint16_t Ch0target=CENTERDEFLECT;				// target voltage output values 10 bit for ch0,1,2
   uint16_t Ch1target=CENTERDEFLECT;

   uint16_t Ch0fact; 
   uint16_t Ch1fact;

   uint8_t i=3;							// Loop index
   uint8_t keyread=127;						// Keyboard vector
   uint8_t keyread_old=0;					// backup byeboard vector for debouncing
   uint8_t keybrake=KEYSPEED;				// ADC cycles between key readouts - determines key rate
   uint8_t accelerate=0;					// counter for acceleration delay

  _delay_ms(STARTUPDELAY);                      		// Wait for supply voltage to stabilize
								// Initialize ports
   DDRA  = (1<<CH0DAC)| (1<<CH1DAC)| (1<<LEDPIN);  // configure output Pins DACs and LED
   DDRB  = 0;							// Port B is completely Input
   PORTB = 127; 						// activate internal pullups for all Keys in Port B except MCU reset
  

   

   
   while(PINB<127);         					// Wait for all Keys to be released
   _delay_ms(DEBOUNCETIME);                       		// Debounce keys
   while(PINB<127);						// Scan keys again
   
//   while(i>0)
//   {								// establish center position on all channels
//    i=0;							// i used as error counter here. Reset it first.
//    Ch0fact=ADCstep(0);							// Sample ch1
//    if ((Ch0target-Ch0fact)>TOLERANCE) i++;				// compare and log discrepancies
//    if ((Ch0fact-Ch0target)>TOLERANCE) i++;
//    if (Ch0fact<Ch0target) sbi(PORTA,CH0DAC); else cbi(PORTA, CH0DAC);	// DAC toggle

//    Ch1fact=ADCstep(1);
//    if ((Ch1target-Ch1fact)>TOLERANCE) i++;				// the same for ch1
//    if ((Ch1fact-Ch1target)>TOLERANCE) i++;
//    if (Ch1fact<Ch1target) sbi(PORTA,CH1DAC); else cbi(PORTA, CH1DAC);

  
//   }									// loop until all center positions reached

//-------------------------------------------------------------------------------------------------------------------
   while(1) 					// infinite main loop - repeat until weihnachten
   {
    for(i=0; i<keybrake; i++)			// Do the DAC loop
     {
      Ch0fact=ADCstep(0);							
      if (Ch0fact<Ch0target) sbi(PORTA,CH0DAC); else cbi(PORTA, CH0DAC);	

      Ch1fact=ADCstep(1);
      if (Ch1fact<Ch1target) sbi(PORTA,CH1DAC); else cbi(PORTA, CH1DAC);

    
     }						// End of DAC loop
						// Do the keyboard business
      keyread=PINB;				// read keys	
      if((keyread==keyread_old)&&(keyread<127)) // Key pressed and held for 2 main loops
      
	  {
       if(bit_is_clear(keyread, CH0UPKEY)&&(Ch0target<MAXDEFLECT)) Ch0target++;
       if(bit_is_clear(keyread, CH1UPKEY)&&(Ch1target<MAXDEFLECT)) Ch1target++;
    
     
       if(bit_is_clear(keyread, CH0DOWNKEY)&&(Ch0target>MINDEFLECT)) Ch0target--;
       if(bit_is_clear(keyread, CH1DOWNKEY)&&(Ch1target>MINDEFLECT)) Ch1target--;
     
         
       if(bit_is_clear(keyread, CENTERKEY))
       {     
        Ch0target=CENTERDEFLECT;
        Ch1target=CENTERDEFLECT;
   
       }
       
	   if (accelerate<KEYSTEPS) accelerate++;
	   
	   
	   
       if ((keybrake>KEYLIMIT)&&bit_is_set(keyread,CENTERKEY)&&(accelerate>=KEYSTEPS)) 
	   { 
	     keybrake--; //speed up repetition rate if key pressed   
		 accelerate=0;
       }
      }
       else 
		{ 
		 keybrake=KEYSPEED;			// No keys pressed: set to initial key repetition rate
         accelerate=0;				// reset acceleration delay 
			
		}
  
      keyread_old=keyread; 
   }						// End of infinite loop
}						// End of program
 

Sender-Neigetechnik hatte ich mir (nach den unbefriedigenden Ergebnissen mit dem HeadTracking) auch überlegt, aber das schien mir nicht bewusst kontrolliert genug, wenn ich gleichzeitig noch einen Flieger steuern muss. Bei mir sind das meist Flächenflieger gewesen, die aktiv geflogen werden wollten - keine von Alleine am Himmel klebenden Multikopter.