- 3D-Druck Einstieg und Tipps         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 15 von 15

Thema: 1S LiPo Überwachung

  1. #11
    Erfahrener Benutzer Roboter Genie Avatar von Crazy Harry
    Registriert seit
    15.01.2006
    Ort
    Raum Augsburg - Ulm
    Beiträge
    1.308
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Der Tastkopf sieht echt gut aus und so teuer finde ich den nicht. Ist das tatsächlich ein auf 10:1 fest eingestellter Kopf und nicht auf 1:1 umschaltbar? Trotzdem könnte ich mir da mal 2 gönnen .

    Kannst mir das Layout trotzdem schicken? Würde mich interessieren ob ich das hin bekomm bei 0.95mm Pinabstand. Aber wenn dann dxf. Ich hab nur eine uralte Eagle-Lizenz.

    Letztes Bild 15MHz Sinus?

    Gruss
    Harry
    Ich programmiere mit AVRCo

  2. #12
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Der Tastkop ist immer 1:10 lässt sich nicht umschalten.
    Die 15 MHz waren natürlich kein Sinus, ich wollt nur zeigen dass beide Signale identisch sind.

    Hier ist ein 15 MHz Sinus, mehr gibt mein Generator nicht her.
    Klicke auf die Grafik für eine größere Ansicht

Name:	K110_LiPo_Blitzer_20.jpg
Hits:	10
Größe:	79,1 KB
ID:	35017

    mal gucken wie das geht mit dem DXF, habe ich noch nie benötigt.
    Habe einen Eagle 5.9.0 also hoch aktuell....

    ich weis garnicht wie ich Dir eine Datei schicken kann... bei email finde ich gar keine Möglichkeit für Anhang.
    geht das überhaupt über das Forum
    Geändert von Siro (15.05.2020 um 20:50 Uhr)

  3. #13
    Erfahrener Benutzer Roboter Genie Avatar von Crazy Harry
    Registriert seit
    15.01.2006
    Ort
    Raum Augsburg - Ulm
    Beiträge
    1.308
    Du hast ne PM von mir
    Ich programmiere mit AVRCo

  4. #14
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Ich habe meine Akkuüberwachung verbessert:

    Jetzt hat der Hubi eine LED-Leiste auf dem HECK mit 18 RGB Leds Größe 2020.
    Die Ansteuerung erfolgt über die identische Elektronik, da hab ich nichts geändert.
    Aber die Software musste natürlich extrem angepasst werden.
    Der PIC hat leider sehr wenig RAM und da musste ich etwas tricksen und habe notgedrungen
    sogar unbenutzte File-Register mitbenutzt.
    Das Assschieben der RGB Daten ging nur in Assembler, der C-Compiler hat mir keinen einwandfrei lauffähigen Code erzeugt,
    er benötigte auch zu viel RAM.

    Bei vollem Akku sind alle LEDs grün,
    je nach Spannung wechseln immer mehr LEDs zu rot, bis die kritische Schwelle 3,2 Volt erreicht ist,
    dann blinkt die gesamte Kette abwechseln rot / blau.

    RA2 ist der RGB Datenstrom

    Über die Leitung RA3 kann zusätzlich die Helligkeit auf FULL oder HALF eingestellt werden.
    RA3 low LED heller 0xFF
    RA3 high LED dunkler 0x7F

    Die vorhandenen beiden LEDs auf der Leiterplatte, aus der ursprünglichen Schaltung /Software bliken dann zusätzlich wie gehabt abwechselnd.

    Videos mit LEDs scheint generell problematisch zu sein,
    aber ich hoffe man sieht trotzdem die Funktionsweise.

    https://www.dropbox.com/s/c5lvxdgf3n...2_RGB.mp4?dl=0

    Siro

    der Code:

    Code:
    /* 
      File:   main.c
      Date:   06.02.2021  
      Author: Siro
    
      Projekt: 10F322  RGB-Ansteuerung 
      18 LEDs für den K110 Hubschrauber
      Einige Assembler Optimierungen vorgenommen
      !!! PMDATH und PMDATL sind nicht initialisiert nach einem Reset
      250ns Instruction Cycle, 4 MHz
    
      Der Stripe mit 18 LEDs zieht knapp 100mA bei voller Helligkeit "einer" von 3 LEDs ROT oder GRÜN oder BLAU
      Bei halber Helligkeit 0x7F nur ca. 50mA
    
      RA3 low  LED heller  0xFF 
      RA3 high LED dunkler 0x7F
    
      Stripe mit 18 LEDs wiegt knapp 0,6 Gramm
      Auch bei 1,65 Volt lief die Schaltung noch mit LEDs !!!!!
      die blauen LEDs brauchen aber mindestens 2,5 Volt und sind dann noch recht dunkel
    */
     
    // PIC10F322 Configuration Bit Settings
    // 'C' source line config statements
    
    // CONFIG
    #pragma config FOSC = INTOSC    // Oscillator Selection bits (INTOSC oscillator: CLKIN function disabled)
    #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
    #pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
    #pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
    #pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
    #pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
    #pragma config LPBOR = OFF      // Brown-out Reset Selection bits (BOR disabled)
    #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    
    #include <xc.h>   // die einzige Headerdatei die benötigt wird.
    
    // benötigen wir nicht, das Delay erzeugen wir selbst mittel Timer 0
    // #define _XTAL_FREQ 16000000  // für 4 MHz instrction cylce time wegen der 4 stage pipeline 
    
    /*----------------------------------------------------------------------*/
    /* hier habe ich meine eigenen Datentypen definiert:  */
    typedef unsigned char BOOL;   /*  0=FALSE,  all others are TRUE */    
    typedef unsigned char   U8;   /*  8 Bit ohne Vorzeichen */
    typedef signed   char   S8;
    typedef unsigned short U16;   /* 16 Bit ohne Vorzeichen */
    typedef unsigned long  U32;   /* 32 Bit ohne Vorzeichen */
    
    /* dem Datentyp BOOL sollten nur diese Konstanten zugeordnet werden:    */
    #define FALSE (0)            /* Eine 0  bedeutet FALSE (falsch)         */
    #define TRUE  (!FALSE)       /* alle anderen Werte bedeuten TRUE (wahr) */
    
    // Die HARDWARE : 2 LEDs, 1 RGB Stripe WS2812 / SK68 kompatibel mit 18 LEDs
    
    // LED 1 connected to pin RA0
    #define LED1_ON  LATA0=1 
    #define LED1_OFF LATA0=0
    
    // LED 2 connected to pin RA1
    #define LED2_ON  LATA1=1 
    #define LED2_OFF LATA1=0
    
    // Declaration einer einzelnen RGB LED 
    // Jede LED hat 3 Bytes, insgesamt also 24 Bits 
    typedef struct // __pack ? bei 8 Bittern unnötig ist immer packed
    {
      U8 green; /* 8 Bit fuer die Helligkeit gruen */
      U8 red;   /* 8 Bit fuer die Helligkeit rot   */
      U8 blue;  /* 8 Bit fuer die Helligkeit blau  */
    } TLed;     /* Type Bezeichner ist TLed */
    
    #define LED_COUNT 18         // Anzahl der anzusteuernden RGB Leds max 18 ???
    
    TLed LedArray[LED_COUNT];   // gesamtes Datenarray der Ledkette 
    // dieses Array wird dann per Assmblercode ausgeschoben
    
    // U8 ArraySize = sizeof(LedArray);  // die Groesse des Arrays in Bytes
    
    // hier liegt eine Tabelle mit den ADU Werten für die entsprechende Spannung
    // ADU ==> Voltage.
    const U8 ADU_Table[] = 
    {
      161,  // 3,25
      160,  // 3,28
      158,  // 3,31
      157,  // 3,34
      156,  // 3.37
      154,  // 3,40
      153,  // 3,43
      152,  // 3,46
      150,  // 3,39
      149,  // 3,52
      148,  // 3,55
      146,  // 3,58
      145,  // 3,61
      144,  // 3,64
      143,  // 3,67
      142,  // 3,70
      141,  // 3,73
      128   // 4,10 
    };
    
    
    //------------------------------------------------------------------------------
    // für 250ns Instruction Cycle Time 4 MHz
    // PMDATL enthält das auszuschiebene Datenbyte für die WS2812 RGB-Led Kette
    // wird also als Zwischenspeicher benutzt. (8 Bit Register)
    // PMADRL wird für den Bytezähler benutzt  (8 Bit Register)
    // PMDATH wird als Bitzähler benutzt !!! ist nur ein 6 Bit Register
    // das reicht aber, wir zählen ja nur von 8 bis 0
    // !!! PMDATH ist nach reset nicht initialisiert, aber selbst mit dem Wert FF
    // habe ich das optisch nicht wahrnehmen können.
    
    void asm_LedShiftOut(void)
    {
    //  asm ("clrf  PMDATH");    // wegen  optimierten bsf PMDATH,3  in der NextByte Loop 
    //  asm ("incf  PMDATH,F");  // testweise mal gucken
      
      GIE=0;                       // global interrupt disable
      
      asm("movlw LOW _LedArray");  // address of LedArray
      asm("movwf FSR");            // to FSR index register
    
      asm("movlw 18*3");
      asm("movwf PMADRL");         // use PMADRL as byteCount
      
    asm("Label_NextByte:");        // !! WICHTIG, der Doppelpunkt ab XC8 V2.20
      asm("bsf   PMDATH,3");       // PMDATH = 8
      asm("movf  INDF,W");         // load byte from LedArray
      asm("movwf PMDATL");         // save Databyte to PMDATL 
    
    asm("Label_ByteLoop:");
      asm("btfsc PMDATL,7");       // scip if databit is clear (MSB)
      asm("goto Label_High");      // else databit ist set
      asm("bsf LATA,2");           // set WS2812 DataLine to High 250ns
      asm("bcf LATA,2");           // set WS2812 DataLine to Low
      asm("goto Label_nextBit");
     
    asm("Label_High:");            // High Databit
      asm("bsf LATA,2");           // set WS2812 DataLine to High
      asm("goto $+1");
      asm("bcf LATA,2");           // set Line to Low
    
    asm("Label_nextBit:");
      asm("rlf PMDATL,F");          // databyte left
      asm("decfsz PMDATH,F");       // bitCount-1, scip if all bits done, bit count -1
      asm("goto Label_ByteLoop");   // next bit
      
      asm("incf FSR,F");            // address pointer to next Led Byte
      asm("decfsz PMADRL,F");       // byteCount-1 scip if all bytes done
      asm("goto Label_NextByte");   // else send next byte
    
      GIE=1;                        // global interrupt enable
    
      //   __delay_us(100); // Das Ende der Datenübertragung erreicht wenn die Leitung länger als 50us Low bleibt.
      //  !!! mindestens 80us bei SK68 Leds 
        
    // hier brauche ich eigentlich nicht warten, weil der restliche Programmcode benötigt ja schon die Zeit ???
    //   asm("movlw 0x85");           // das sind 100us 
    //   asm("movwf PMDATL");
    //   asm("Label_delay100:");
    //   asm("decfsz PMDATL,F");
    //   asm("goto Label_delay100");
    
    // asm("NOP");   // nur um Breakpoint zu setzen, Zeit messen
    }
    //------------------------------------------------------------------------------
    // global interrupt function
    // PWM1DCH wird runtergezählt wenn noch nicht 0
    // PWM1DCH dient also als globale Zählvariable
    
    void __interrupt() isr(void)    // ORG 0x0004
    {
      TMR0   = 100;  // restart timer 0 value for 10ms
      TMR0IF = 0;    // clear the timer 0 interrupt flag
    
      if (PWM1DCH)   // wenn die Zählvariable noch nicht 0 ist,
        PWM1DCH--;   // dann ziehen wir eins ab.
    }
    //------------------------------------------------------------------------------
    // PWM1DCH wird im Timer 0 Interrupt alle 10ms um eins runtergezählt
    // solange der Wert noch nicht 0 ist. 
    // !! RAM ist knapp:
    // PWM1DCH wird als Zählvariable benutzt, ein 8 Bit Register welches wir nicht 
    // benötigen. 
    void Delay_10ms(U8 cnt)
    {
      PWM1DCH = cnt;      // setzte Wert für 10ms * cnt
      while (PWM1DCH) ;   // warte bis count 0 wird.
    }
    
    //------------------------------------------------------------------------------
    void FillGreen(void)   // wird nicht benutzt
    { U8 i;
      for (i=0; i<LED_COUNT; i++)
      {
        LedArray[i].red   = 0x00;
        LedArray[i].green = 0x7F;
        LedArray[i].blue  = 0x00;      
      }  
    }
    
    void asm_FillGreen(void)   // wird nicht benutzt
    { 
      asm("movlw LOW _LedArray");  // address of LedArray
      asm("movwf FSR");            // to FSR index register
    
      asm("movlw 18");           // LED_COUNT  Led Counter
      asm("movwf PMADRL");       // use PMADRL as counter
    
    asm("FillGreenLoop:");  
      asm("movlw 0x7F");
    
      asm("movwf INDF");         // save byte to Array .green
      asm("incf FSR,F");
      
      asm("clrw");
      asm("movwf INDF");         // save byte to Array .red
      asm("incf FSR,F");  
      
      asm("movwf INDF");         // save byte to Array .blue 
      asm("incf FSR,F");  
     
      asm("decfsz PMADRL,F");
      asm("goto FillGreenLoop");  
    }
    
    void asm_FillRed(void)
    { 
      asm("movlw LOW _LedArray");  // address of LedArray
      asm("movwf FSR");            // to FSR index register
    
      asm("movlw 18");           // LED_COUNT  Led Counter
      asm("movwf PMADRL");       // use PMADRL as counter
    
    asm("FillRedLoop:");
      asm("clrw");
      asm("movwf INDF");         // save byte to Array .green
      asm("incf FSR,F");
      
      asm("movlw 0x7F");
      asm("movwf INDF");         // save byte to Array .red
      asm("incf FSR,F");  
      
      asm("clrw");
      asm("movwf INDF");         // save byte to Array .blue 
      asm("incf FSR,F");  
     
      asm("decfsz PMADRL,F");
      asm("goto FillRedLoop");  
    }
    
    void asm_FillBlue(void)
    { 
      asm("movlw LOW _LedArray");  // address of LedArray
      asm("movwf FSR");            // to FSR index register
    
      asm("movlw 18");           // LED_COUNT  Led Counter
      asm("movwf PMADRL");       // use PMADRL as counter
    
    asm("FillBlueLoop:");
      asm("clrw");
      asm("movwf INDF");         // save byte to Array .green
      asm("incf FSR,F");
      
      asm("movwf INDF");         // save byte to Array .red
      asm("incf FSR,F");  
      
      asm("movlw 0x7F");
      asm("movwf INDF");         // save byte to Array .blue 
      asm("incf FSR,F");  
     
      asm("decfsz PMADRL,F");
      asm("goto FillBlueLoop");  
    }
    
    //------------------------------------------------------------------------------
    void Calculate(void)
    { U8* p = (U8*)LedArray;
      U8 i;
      
      for (i=0; i < sizeof(ADU_Table); i++)
      {  
        if (ADRES < ADU_Table[i])    // kleiner weil ADU Werte invertiert laufen
        { 
          if (RA3) *p++=0x7F;   // green
              else *p++=0xFF;   // more light if jumper RA3 is set
          *p++=0x00;            // red 
          *p++=0x00;            // blue
        } else
        {  
          *p++=0x00;            // green
          if (RA3) *p++=0x7F;   // red
              else *p++=0xFF;   // more light if jumper RA3 is set
          *p++=0x00;            // blue
        } 
      }  
    }
    
    //------------------------------------------------------------------------------
    // internal FRC Conversion time measured 26,50µs for one conversion
    // we calculate the average value over 128 measurements
    // RAM ist knapp: 
    // Schleifenvariable i wird direkt im Register PMDATL ausgeführt
    // Laufzeit ca. 3,8ms
    
    void ReadAdu(void)
    { U16 value;
    
    //  LATA1 = 1;  // testweise fuer die Zeitmessung
       
      value = 0;
      for (PMDATL=0; PMDATL<128; PMDATL++)
      { 
        GO_nDONE = 1;       // start ADU conversion 
        while (GO_nDONE) ;  // wait until adu ready
        value+=ADRES;       // add the result
      } 
      value >>=7;           // divide by 128
      ADRES=(U8)value;      // write back the filtered ADU result
      
    //  LATA1 = 0;    // testweise fuer die Zeitmessung
      
    }  
    //------------------------------------------------------------------------------    
    void main(void) 
    {
      PMDATH = 0;         // ! register not initialized on reset
                          // used only in asm_LedShiftOut as bitcounter
      
      OPTION_REG = 0x07;  // prescale to timer 0, 1:256, enable pullups
                          // !!!! Pullps enabled with LOW on Bit 7
    //  WPUA   = 0x08;      // Pullup only on RA3, all pullups enable at power on
      OSCCON = 0x70;      // 16 MHz clock
      INTCON = 0xF0;      // enable global, peripheral, timer 0 interrupts
      TRISA  = 0x08;      // all pins to output, RA3 is input only  
      
      // internal fixed voltage reference
      // set first the FREN Bit before changing the gain bits
      // see errata sheet
      FVREN  = 1;        // Fixed Voltage Reference is enabled
      ADFVR1 = 1;        // select the 2,048 Volt Reference
      
      // init the ADC
      // ANSELA=1;   AN0 as analog input, all others as digital output
      // we dont need an ADU input, always convert the fixed voltage reference 
      ADCON = (0x07 << 5)    // conversion clock internal FRC
           // + (0x00 << 2)  // select channel AN0, we dont need a channel
            + (0x07 << 2)    // select Fixed Voltage Reference  
            + (0x01 << 0);   // ADC enable
      
      while (1)   // the main loop
      { 
        ReadAdu();         // with average filter
        if (ADRES > 161)   // !! Abfrage invers < 3,25 Volt Unterspannung
        {
          asm_FillRed();
          asm_LedShiftOut();  // RGB LEDs ausschieben
          Delay_10ms(25);
          LATA0 = 1;          // erste  LED Wechselblinker am Heck
          LATA1 = 0;          // zweite LED Wechselblinker am Heck
         
          asm_FillBlue();
          asm_LedShiftOut();  // RGB LEDs ausschieben
          Delay_10ms(25); 
          LATA0 = 0;          // erste  LED Wechselblinker am Heck
          LATA1 = 1;          // zweite LED Wechselblinker am Heck 
        } else 
        { 
           Calculate();       // calculate the RGB Bargraph
           asm_LedShiftOut();    
           Delay_10ms(2);     // 20ms  Anzeige 
          LATA0 = 1;          // erste  LED Wechselblinker am Heck
          LATA1 = 1;          // zweite LED Wechselblinker am Heck 
        } // else
      } // while 
    
    } // main
    Geändert von Siro (20.04.2021 um 20:33 Uhr)

  5. #15
    Neuer Benutzer Öfters hier
    Registriert seit
    27.05.2024
    Beiträge
    5
    Die Ablehnung des C-Compilers wegen des angeblichen RAM-Bedarfs ohne genauere Erläuterung wirkt etwas undurchsichtig. Eine klarere Darstellung der spezifischen Probleme mit dem Compiler und warum Assembler die bessere Wahl war, wäre hilfreich gewesen. Außerdem könnte die Beschreibung der RGB-Datenverschiebung und der RAM-Nutzung präziser sein, um Lesern mit weniger technischem Hintergrund ein besseres Verständnis zu ermöglichen.

Seite 2 von 2 ErsteErste 12

Ähnliche Themen

  1. Starterkit: Serverraum-Überwachung
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 01.10.2013, 00:30
  2. Elektromagnet Überwachung
    Von nikolausi im Forum Elektronik
    Antworten: 8
    Letzter Beitrag: 28.07.2011, 20:56
  3. Drahtbruch Überwachung.
    Von sellentin im Forum Elektronik
    Antworten: 19
    Letzter Beitrag: 08.02.2008, 13:06
  4. Roboter überwachung
    Von MiniMax im Forum Elektronik
    Antworten: 6
    Letzter Beitrag: 30.07.2007, 17:17
  5. Überwachung von Bleiakkus?
    Von Klingon77 im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 27.09.2006, 18:32

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen