- LiFePO4 Speicher Test         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 30

Thema: Morsecode und Bitverschiebung

  1. #11
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.112
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Mit R2D2s Methode geht es zwar, bei größeren Zahlen jedoch stößt die Modulo Operation an ihre Grenzen bzw erzeugt unnötig großen Code und damit Rechenzeit, was in zeitkritischen Anwendung ausgeschlossen ist.
    Es geht auch mit den Grundrechenarten, für den Controller je nach Zahlengröße schneller gerechnet:
    Code:
    Int Zahl = 12345;
    Stelle_5 = Zahl / 10000;  // =1
    Stelle_4 = Zahl - Stelle_5*10000 / 1000;  //=2
    ...
    Das kann man jetzt auch noch optimieren, aber so versteht man es besser.
    Gruß

  2. #12
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    15.04.2008
    Beiträge
    330
    @Gock

    Ich glaube hiermit habe ich das selbe geschrieben (Idee hab ich beim Surfen gefunden):

    Code:
    uint16_t readADC(uint8_t channel) 
    {
    	// Funktion 1 zum Auslesen der Spannung
    
    	uint8_t i;                   // Variablen definieren (Zählervariable i + Resultat)
    	uint16_t result = 0;
    
    	ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1); //ADEN = ADC Enable 
    	// wenn adps1+2 on sind und adps0 off, dann ist der Teilungsfaktor 64 (Tabelle Datasheet)
    
    	ADMUX = channel; //Kanal wählen; REFs0+1 -> interne Referenz 2,56V verwenden, REFS1 gibt es bei Attiny13 nicht
    	//externen Kondensator mit 100nF (Aufdruck 104) an AREF auf Masse
    
    	//Dummy-Readout (unten), misst 1* Ergebnis, wird nicht gespeichert
    	ADCSRA = ADCSRA | (1<<ADSC); // Schaltet bei ADCSRA das ADSC-Bit ein, d.h. Messung starten
    	while(ADCSRA & (1<<ADSC)); //Warte bis Messvorgang vorbei ist
    
    	// Nun 3* Spannung auslesen, Durchschnittswert ausrechnen
    	for (i=0; i<3; i++) 
    	{
    		// Schleife, startet 3*
    		ADCSRA = ADCSRA |(1<<ADSC); // Einmal messen
    		while(ADCSRA & (1<<ADSC));  //Warte bis Messung vorbei
    
    		result = result + ADCW; // Resultate zusammenzählen (R1+R2+R3) -> später alles /3
    	}
    
    	ADCSRA = ADCSRA & (~(1<<ADEN)); //ADC wieder deaktivieren
    
    	result=result/3;    // Durchschnittswert
    
    	return result;
    }
    
    main ()						// Hauptprogramm, startet bei Power ON und Reset
    {
    	int spannung; //Definiere Ganzzahl-Variable Spannung
    	int einer,zehner, hunderter, startwert, mittelwert, endwert;
    	int i,j,k = 0;
    
    	DDRB=0b00001111;
    
    	while (true)
    	{
    
    		uint16_t result = readADC(0); // ruft die ADC Funktion auf an Pin0 =ADC0
    
    		spannung = result*3086;
    		spannung = spannung/1000; 
    
    		startwert=spannung/10;
    		hunderter=startwert/100;
    		mittelwert=startwert-100*hunderter;
    		zehner=mittelwert/10;
    		endwert=mittelwert-10*zehner;
    		einer=endwert;
    
    		for (i=0;i<einer;i++)
    		{
    			PORTB=PORTB|(1<<PB0);
    			waitMs(50);
    			PORTB=PORTB&(~(1<<PB0));
    			waitMs(50);
    		}
    
    		for (j=0;j<zehner;j++)
    		{
    			PORTB=PORTB|(1<<PB1);
    			waitMs(50);
    			PORTB=PORTB&(~(1<<PB1));
    			waitMs(50);
    		}
    
    		for (k=0;k<hunderter;k++)
    		{
    			PORTB=PORTB|(1<<PB2);
    			waitMs(50);
    			PORTB=PORTB&(~(1<<PB2));
    			waitMs(50);
    		}
    
    		waitMs(1100);
    
    	}
    
    	return 0;
    }
    Der Code klappt zum draufbrennen, aber in der Schaltung funktioniert er nicht... HAb ich nen Fehler eingebaut??

  3. #13
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.112
    Gelöscht, war.Unsinn
    Aber bei mir oben ist auch ein kleiner Fehler: Hab die Klammer vergessen...
    Code:
    Int Zahl = 12345;
    Stelle_5 = Zahl / 10000;  // =1
    Stelle_4 = (Zahl - Stelle_5*10000) / 1000;  //=2345/1000=2
    ...
    Gruß

  4. #14
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    15.04.2008
    Beiträge
    330
    Hey, glaube das stimmt schon.

    Spannung ist nicht 3086, sondern (ADC)result (0...1024) * 3086;

    Dh. zb. 1023*3086 also 3156978.... Das durch 1000 ist 3156 mV !

  5. #15
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.112
    Hast natürlich recht, hab die Multiplikation ignoriert.
    Der Code sieht eigentlich gut aus beim Überfliegen.
    Was funktioniert denn nicht genau?
    Gruß

  6. #16
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    15.04.2008
    Beiträge
    330
    Kann passieren

    Naja, der Code wird vom AVR-Workpad raufgebrannt, und er schreibt ''erfolgreich gebrannt''...

    Das heißt, wenn ich den Chip in die Schaltung gebe, müsste es gehen.

    Ich stecke ihn also in die AVR-Chip-Halterung und schließe die Batterie an... Die Schaltung müsste dann funktionieren, tut sie aber nicht... (Momentan habe ich keine LED an den Pin der einerstelle angeschlossen, das sollte aber kein Problem sein... )

    Nichts leuchtet oder blinkt...

  7. #17
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.112
    Du scheinst einen Tiny13 zu benutzen und willst ADC0 auslesen. Der zugeordnete Pin ist auch der Reset!
    Hast Du das entsprechend gefust? -> Datenblatt "Table 10-4. Overriding Signals for Alternate Functions in PB5:PB3"
    Aber Achtung, wenn Du den Reset deaktivierst, kannst Du danach nicht mehr mit Deinem Brenner zugreifen. Nimm also lieber einen anderen ADCPin.
    Gruß

  8. #18
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    15.04.2008
    Beiträge
    330
    Hey, Danke. Das ist eine Idee... werd mal versuchen, das auf den ADC1 zu legen...

    (zu den waitMs(50), da muss ich nochml umschreiben, aber normalerweise ist die Taktung automatisch falsch eingestellt, dass 50Ms ca. 300-500 sind, man es also sieht... Könnte auch dran liegen, dass es diesmal irgendwie die richtige Taktung ist und man die Blinksignale einfach nicht sieht... Aber sehr unwahrscheinlich...)

  9. #19
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    15.04.2008
    Beiträge
    330
    Hey,

    habe gerade folgendes Programm ausprobiert


    Code:
    int hunderter=5;
    int i;		
    
    main ()	
    					
    {
    
    	while (true)
    	{
    	for (i = 0; i < hunderter; i++) 
    	  {
    
    		PORTB=PORTB|(1<<PB1);
    		waitMs(100);
    		PORTB=PORTB&(~(1<<PB1));
    		waitMs(100);
            }
            
            waitMs(1100);
    	}
    }
    Das sollte doch gehen, oder?

    Nur, bei mir leider wieder mal nicht

    Hunderter soll hierbei den Hunderterwert einer gemessenen Variable sein, provisorisch habe ich sie mal auf 5 gesetzt, um zu sehen, ob dieses Minimalprogramm geht.... Leider eben nicht. Wäre echt grooßartig, falls mir da jemand weiterhelfen könnte...!

  10. #20
    Erfahrener Benutzer Roboter Experte Avatar von BurningWave
    Registriert seit
    22.12.2007
    Ort
    nahe Stuttgart
    Alter
    29
    Beiträge
    656
    Globale Variablen sind nicht gut, int i kann im Kopf der Schleife erstellt werden:

    Code:
    int hunderter=5;     
    
    main ()                    
    { 
       while (true) 
       { 
       for (int i = 0; i < hunderter; i++) 
         { 
    
          PORTB |= (1<<PB1); 
          waitMs(100); 
          PORTB &= ~(1<<PB1); 
          waitMs(100); 
            } 
            
            waitMs(1100); 
       } 
    }
    Im Prinzip sollte es funktionieren, vorausgesetzt, deine waitMs arbeitet richtig. Schau dir mal die _delay_ms(x) Funktionen aus der util\delay.h an.
    meine Homepage: http://www.jbtechnologies.de
    Hauptprojekte: Breakanoid 2 - Sound Maker

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress