RC Schalter (Load Switch)

Hallo,

ich hab hier eine kleine Schaltung welche über einen RC-Kanal eine Last schaltet.
Die Impulslänge vom Schaltkanal wird mit einem PIC12F1572 über eine Interrupt Routine gemessen.
Dazu wird das Servosignal auf den externen INT-Eingang vom PIC gelegt. Der Interrupt wird auf
steigende Flanke initialisiert. Es wird ein 16-Bit Timer Wert 1 gespeichert. Dann wird der EXT INT auf fallende Flanke
initialisiert. Speicherung vom Timer Wert 2. Somit hat man die Servo Pulslänge gemessen. Über eine in der SW einstellbare
Impulslänge wird dann eine Last über einen N-Kannal Logic Level FET geschaltet. Mit dem FET IRLML 2502 können Lasten
bis zu 4.2 A geschaltet werden. Aufgrund der Bauteilgrösse (SOT-23) sind die 4.2 A nur für eine kurze Zeitdauer gedacht.
Damit kann man aber durchaus eine 10W LED als Blitzer schalten. Die Versorgung Vsupply muss dann natürlich über den Antriebsakku (Balancerstecker) erfolgen. Ich hab damit ein 12 LED Cluster mit integrierten Vorwiderständen geschaltet. Die Versorgung erfolgt
über den Empfänger, der Strom liegt bei dem 12 LED Cluster bei etwa 250 mA. Man kann auch direkt einen 5V SUMMER TDB 05 ansteuern,
verwende ich als Modellfinder. Die Platine hat die Abmasse 17x25 und kostet etwa 1.5 Euro.

PIC 12F1572, 0.99 Euro reichelt.de
IRLML 2502, 0,18 Euro reichelt.de
SUMMER TDB 05, 0,99 Euro reichelt.de

Gruss Micha

RC-Switch.jpg

Code:
'  RC switch
'  Michael Schulz 21.12.2017
'  Compiler Version 0.97.01 2017-02-20
'
'                    -----------
'  V+              -| 1       8 |- GND
'  RA5             -| 2       7 |- RA0 LOAD
'  RA4             -| 3       6 |- RA1
'  RA3             -| 4       5 |- RA2/INT SERVO_PULSE
'                    -----------
'
'
#chip 12F1572,8
#config OSC = INTOSC, PWRTE = ON

#define SERVO_PULSE PORTA.2
dir SERVO_PULSE in

#define LOAD PORTA.0
dir LOAD out

dim TimerValue as word
dim TimerValue1 as word
dim TimerValue2 as word

dim RISING_EDGE as byte

'init
TimerValue = 0
TimerValue1 = 0
TimerValue2 = 0
RISING_EDGE = TRUE

#define MSEC_1P7 1700

InitTimer1 Osc, PS1_2 '  8 Mhz/4/2, 1 us resolution
StartTimer 1

bsf OPTION_REG,INTEDG ;set external interrupt on rising edge
On Interrupt ExtInt0 Call ISR1 'external interrupt on RA2

Do
   if (TimerValue > MSEC_1P7) then
      set LOAD on
      wait 100 ms
      set LOAD off
      wait 400 ms
   end if
Loop
'******************************************************************************

sub ISR1 'external interrupt on RA2
    if (RISING_EDGE) then
       TimerValue1 = Timer1
       RISING_EDGE = FALSE
       bcf OPTION_REG,INTEDG  ; set external interrupt on falling edge
       goto FIN_RISING_EDGE ' jump to FIN_RISING_EDGE
    end if

    if (not RISING_EDGE) then
       TimerValue2 = Timer1
       RISING_EDGE = TRUE
       if (TimerValue2 >= TimerValue1) then
          TimerValue = TimerValue2 - TimerValue1
       else
          TimerValue = (0xFFFF - TimerValue1) + TimerValue2
       end if
       bsf OPTION_REG,INTEDG ;set external interrupt on rising edge
    end if
    FIN_RISING_EDGE:
end sub
 
Hallo Micha
Mit einem Sot23 Fet könnt man auch so nen süßen Sot23 Attiny10-Krümel nehmen ?
kruemel_at10.jpg

Mal schnell nen Code hingebabbt, PB1 RC, schaltet an PB 2 ne LED überm Senderknüppel.
Code:
#ifndef F_CPU
#define F_CPU 8000000UL
#endif
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>   
   
int main(void){
DDRB    |= 0b00000100;  // BP2 FET
PORTB   |= 0b00000010;  // PB1 RC
PUEB    |= 0b00000010;  // PB1 RC
PCICR    = 0b00000001;
PCMSK    = 0b00000010;
TCCR0B   = 0b00000010;
sei();
while(1){}}

ISR(PCINT0_vect){
if(PINB&(1<<PB1)){TCNT0=0;}
else{   if (TCNT0>180) {PORTB  &= ~_BV(PB2);}
          else         {PORTB  |=  _BV(PB2);}
}}
 
Servoverteiler / Mehrfachschalter Summsignal

Servoverteiler / Mehrfachschalter Summsignal

Moin Leute

Noch was zum teilen, falls es jemand gebrauchen kann. Eingang Summsignal, 4Ausgaänge, wahlweise irgend ein Servosignal oder Schaltkanal.
Beispiel,
-4Servos in einer F3K Fläche, dann braucht nur noch ein Servokabel zum Rumpf in Empfänger, spart mächtig Gewicht und Kabelverhau.
-2Servos in Fläche, und zwei schaltbare Lichter in der Fläche, auch nur ein Servokabel zum Rumpf.

Als Prozessor eignet sich der Attiny25/45/85. Besonders Interessant, in der Bucht gibt es den Attiny85 als "Arduino" unter Suchbegriff "Digispark" fertig auf Platine mit USB und Spannungsregler (falls HV-BEC) direkt aus China für 1,23€ inkl Porto, aber das USB rannte mir zu wackelig, ich habe den Hagen "One-Wire-Bootloader" draufgespielt, auch gleich auf 8MHz(orginal kommt der mit 16,5MHz) damit kann ich über das Servokabel mit z.B. Hott/JEti/BLHeli Progadapter einfacher Updaten.(Bild:Quelle eBay-Artikelnummer:201743239428)
s-l225.jpg



Wem das zu schwer ist, es gibt auch so Adapterplatinchen in der Bucht, von SMD-Attiny auf DIP8, kosten beim Chinamann 2,98€ 100Stück inkl. Porto. Für 2Servos kann durchaus an der DIP8 Version auch ohen Platine alles anlöten.
Und wem das immernoch noch zu schwer ist, dafür hab ich den Code auch für den Attiny10, der kann aber nur 2Kanäle ausgeben.

Für LED bitte die max. 40mA /Port beachten, ansonsten hat ja Micha oben gepostet wie man da nen FET für höhere Ströme dranhängen kann.

Im Code können oben die Senderkanäle den Ports zugeordnet werden (welcher Kanal kommt aus welchem Pin raus)

In der While-Schleife sind die 4 Schalter, In der ISR Schleife sind die 4 Servoausgänge
Durch auskommentieren // aktivieren oder deaktivieren was gebraucht wird, aufpassen, immer nur eines pro Ausgang, entweder Servo oder Schalter. (Das hätte man auch per Abfrage lösen können, aber dann wäre mir die ISR zu sehr aufgebläht)
Wer weiter basteln will, die Servo-werte liegen dann in channel[x] in bereit zur Weiterverarbeitung, (1100-1900ms, x ist kanalnummer wie vom Sender geliefert).

Sicher kann man hier und da einiges verbessern... aber evtl kanns ja wer gebrauchen.

Code:
#define F_CPU 8000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h> 

byte PB_0 = 1;  //Senderkanal wählen für PB0/D0
byte PB_1 = 2;  //Senderkanal wählen für PB1/D1
byte PB_3 = 5;  //Senderkanal wählen für PB3/D3 
byte PB_4 = 6;  //Senderkanal wählen für PB4/D4 
                            
volatile int OVR, count, channel[16];
int main(void){
DDRB   |= 0b00011011; // OUTPUTs
PORTB  |= 0b00000100; // PB2 RC_Sum
PINB   |= 0b00000100; // PB2 RC_Sum
GIMSK   = 0b01000000; // INT0 aktiv
MCUCR   = 0b00000010; // Falling Edge
TIMSK   = 0b01000110; // INT Overflow 
TCCR0A  = 0b00000000; // nix
TCCR0B  = 0b00000010; // Prescale 1/8   
sei();

while(1){
  if (channel[PB_0] > 1500){PORTB |= _BV(PB0);} else {PORTB &= ~_BV(PB0);}
  if (channel[PB_1] > 1500){PORTB |= _BV(PB1);} else {PORTB &= ~_BV(PB1);}
//if (channel[PB_3] > 1500){PORTB |= _BV(PB3);} else {PORTB &= ~_BV(PB3);}
//if (channel[PB_4] > 1500){PORTB |= _BV(PB4);} else {PORTB &= ~_BV(PB4);}
}}
 
ISR(TIMER0_OVF_vect){OVR++;}
ISR(INT0_vect){
channel[count]=((OVR<<8)+TCNT0);
if (OVR>25){count=1;} else {count++;}
TCNT0=0; OVR=0;

//if (count==PB_0){PORTB |= _BV(PB0);} else {PORTB &= ~_BV(PB0);}
//if (count==PB_1){PORTB |= _BV(PB1);} else {PORTB &= ~_BV(PB1);}
  if (count==PB_3){PORTB |= _BV(PB3);} else {PORTB &= ~_BV(PB3);}
  if (count==PB_4){PORTB |= _BV(PB4);} else {PORTB &= ~_BV(PB4);}
}
 
Hallo Holger,

vielen Dank für deinen Post. Ich hab den RC-Switch als Anregung gepostet. Man kann mit wenig Aufwand vieles selber machen. Mein RC-Switch
ist ein Beispiel, welches durch Posts von weiteren Usern zu neuen Ideen führen kann.

Schöne Weihnachten
Micha
 
Nein ich danke, für die Idee. Durch "Aufgabenstellungen" lernt man schneller (fange mit 50 jetzt erst diese Programmierei an:rolleyes:, grad so der Übergang von Arduino zu C)
 

tukan

User
Mal schnell nen Code hingebabbt, PB1 RC, schaltet an PB 2 ne LED überm Senderknüppel.
Code:
#ifndef F_CPU
#define F_CPU 8000000UL
#endif
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
 
int main(void){
DDRB    |= 0b00000100;  // BP2 FET
PORTB   |= 0b00000010;  // PB1 RC
PUEB    |= 0b00000010;  // PB1 RC
PCICR    = 0b00000001;
PCMSK    = 0b00000010;
TCCR0B   = 0b00000010;
sei();
while(1){}}

ISR(PCINT0_vect){
if(PINB&(1<<PB1)){TCNT0=0;}
else{   if (TCNT0>180) {PORTB  &= ~_BV(PB2);}
          else         {PORTB  |=  _BV(PB2);}
}}

Hallo Allerseits,
ich weiß zwar, der Thread ist etwas älter - hab' diesen aber trotzdem erst gestern gelesen... :)
Für ein aktuelles Projekt brauche ich einen Miniatur-R/C-Schalter und bin hier fündig geworden. EIn paar Attiny 10 liegen auch noch rum, also war auf die Schnelle alles nötige vorhanden.
@Holger Lambertus : Ich habe mir eine kleine Platine geätzt und mit deinem Code im AVR-Studio bzw. Microchipstudio kompiliert und ohne Fehlermeldung auf den Attiny10 per TPI geladen.
Leider macht die Schaltung am Servotester keinen Mucks. Desweiteren muß ich dazusagen, daß ich zwar mit Hardware umgehen kann und inzwischen weiß, wie man einen µC beschreibt, aber programmieren kann ich immer noch nicht.
Das Layout und die Platine habe ich bereits mehrmals auf Fehler überprüft, da scheint alles o.k. zu sein.
Wo könnte auf der Programmierseite der Fehler liegen. Fuses kann man ja nicht großartig setzen...
 
Zuletzt bearbeitet:

tukan

User
Update:
Im Internet habe ich den Hinweis gefunden, daß per Fuse CKOUT der interne Takt an PB2 ausgegeben werden kann. Das habe ich probiert und siehe da, immerhin ein Lebenszeichen vom µC, am Ausgang standen saubere 1MHz. Also lebt der Tiny...
Daraufhin nochmals den fertigen Hex-File ohne CKOUT geflasht und den Tiny versuchsweise eingelötet. Und siehe da, schon beim Einstecken ging die LED am Ausgang 'AN' - beim Drehen am Servotester auf die gegenüberliegende Seite 'AUS'. Leider ist 'Aus' bei maximaler Impulslänge.
Dennoch, die Schaltung funktioniert jetzt zumindest im Grundsatz!
Die invertierte Arbeitsweise habe ich durch ein Umstellen des Codes korrigiert bekommen, nun scheint wirklich alles in Ordnung zu sein. Wo der Fehler denn nun lag, weiß ich allerdings immer noch nicht. Kann es sein, daß die Fuses immer geflasht werden müssen, auch wenn man gegenüber den 'Werkseinstellungen' nichts ändert?

Danke an der Stelle an @Holger Lambertus für den Code !!!

P.S.: Die fertige Platine ist ca 15x10mm, statt der Onboard-LED werden mehrere externe LEDs angeschlossen.
 

Anhänge

  • Attiny10_RC-Schalter_02.jpg
    Attiny10_RC-Schalter_02.jpg
    193,3 KB · Aufrufe: 143
Ansicht hell / dunkel umschalten
Oben Unten