ATmega8-tachometr, měř. pomocí Hallova magnetického senzoru

Zdravým jsem ještě trochu začátečník ale chtěl jsem se poradit se zapojením a naprogramováním jednoduchého tachometru který by měřil pouze otáčky pomocí hallova magnetického senzoru a zobrazoval by rychlost na dvouznakovem sedmisegmentovem led displeji . Děkuji všem za odpovědi.

:arrow_right: administrator: přejmenováno z "atmega8 - tachometr"

Možná by nebylo od věci dát sem aspoň něco, co už máš, abychom věděli, kde začit.

zdravím , jelikož autor už asi neodpoví rád bych využil toto vlákno jelikož bych potřeboval poradit ve stejné věci s tím že zatím mám tohle:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <math.h>

volatile unsigned int namerane;
volatile unsigned int stred;
volatile unsigned int vysledek;
uint8_t PROGMEM znaky] = {0x79, 0x23, 0x30, 0x19, 0x18, 0x02, 0x78, 0x00, 0x10, 0x40};

ISR (TIMER1_CAPT_vect){
	namerane = TCNT1;
	TCNT1 = 0;
}

int main(){
	DDRD=0b11111111;
	DDRC=0b11111111;
	DDRB = 0b11111110;
	PORTB |= (1 << PB0); 
	TCCR1B |= (1 << CS12) | (1 << CS10); 
	TIMSK |= (1 << TICIE1); 
	OSCCAL = 0xA5;   
		
	sei(); 

	while(1){	
		if(namerane) {	
			stred = (namerane/976);
			vysledek = (30/stred);			
                  PORTD = znaky[vysledek];
				  PORTC = znaky[vysledek];
				  _delay_ms(1000);
		   namerane = 0;
		}
		}
return 0;
}

s tím že potřebuji proměnou “vysledek” zobrazit na dvouznakovém sedmisegmentového led displaye

zkoušel jsem ten kód rúzně upravovat ale vúbec mě to nechtělo poslouchat a proto chci poprosit o kontrolu a prípadné doplnění výše umístěného kódu.
předem všem děkuji[/code]

Měl bys uvést ještě i schéma. “Neposlouchá” znamená co, že nezobrazuje nebo že neměří? V prvé řadě bys měl oživit displej - neřešit měření a přerušení, jen jednoduše zapsat na porty LED nějaké číslo, zda se správně zobrazí.

Nejdřív oživ displej :

Máš nadefinováno :

uint8_t PROGMEM znaky] = {0x79, 0x23, 0x30, 0x19, 0x18, 0x02, 0x78, 0x00, 0x10, 0x40};

Na porty posíláš :

PORTD = znaky[vysledek]; PORTC = znaky[vysledek];

  1. Na oba porty (předpokládám, že máš na každém portu jednu segmentovku) posíláš stejná data.
  2. Pokud je výsledek větší, než 9, tak se tam posílá něco, co leží v programové paměti za polem “znaky”.

Takže si udělej smyčku:

for (vysledek=0 ; vysledek<100 ; vysledek++) { PORTD=znaky(int)(vysledek/10)]; PORTC=znaky(int)(vysledek%10)]; }

Až Ti to začne vypisovat 00-01-02-…-97-98-99-00-01-…, pak se začni teprve zabývat přerušením, měřením a zobrazením výsledku.

Pri takom nastaveni sa ale hodnoty 00-99 budu menit tak rychlo, ze nic neuvidis. T vomto pripade by som odporucil vlozit nejaky prikaz pause s casom vacsim ako 100ms. Odporucam to len na odskusanie programu pre display. V ziadnom pripade by sa nieco tak stupidne nemalo uchovat aj v konecnom programe. Na skusanie je to tak akurat :slight_smile:

Pravda - samozřejmě - je třeba hodnoty nejenom zobrazit, ale také dát uživateli čas na to, aby je viděl.

I bez schematu je vidět, že tyto kódy nesedí.

Např. hned NULA:
0x79 = 1111001
Má svítit 6 segmentů, ale v kódu je pět jedniček a dvě nuly.

Nebo JEDNA:
0X23 = 0100011
Mají svítit dva segmenty, ale v kódu jsou tři jedničky a čtyři nuly.

Atd.

Protože je to posunuté - tabulka začíná číslicemi “1”, “2”… a končí číslicemi “9”, “0”, v tom případě to už sedí.

aj tak to nesedi :smiley:

Vzhledem k tomu, že se colin už možná neozve, tak je to asi jedno. :slight_smile:

Prominte že jsem se tak dlouho neozval ale byl jsem pryč.
Ano máte pravdu to pole bylo špatně už jsem to opravil a jednociferná čísla to zobrazuje dobře (timto způsobem : PORTD = znaky[4] ) ale nevím jak zobrazit dvouciferné číslo zkusil jsem tento kod :

#include <avr/io.h>
#include <avr/pgmspace.h>

	unsigned int zobrazit;
uint8_t PROGMEM znaky] = {0xC0, 0x79, 0xA4, 0x30, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x40};

int main(){
	DDRD=0b11111111;
	DDRC=0b11111111;  

	while(1){	
			zobrazit = 71;		
			for (zobrazit=0 ; zobrazit<100 ; zobrazit++) 
			{ 
				PORTD=znaky(int)(zobrazit/10)]; 
				PORTC=znaky(int)(zobrazit%10)]; 
			}
	}
return 0;
}

ale nezobrazilo to nic
a proto se chci zeptat jestli by mi nekdo i po tak dlouhé neprítomnosti neporadil jak tedy zobrazovat cisla od 1 do 99 na dvou znacích sedmisegmentového displeje.
Předem děkuji všem za odpovědi.

ak tam do cyklu for za nastavenie portov nedas nejaky delay, tak ti to bude zobrazovat strasne rychlo. Tak rychlo, ze si to nevsimnes. Daj do toho cyklu for nakoniec _delay_ms(1000); a pripoj kliznicu #include <util/delay.h>.
Na mieste, kde mas _delay_ms(x); ti bude program cakat x milisekund.

Zkus si nejdříve zprovoznit, abys nastavením určitého stavu na výstupních portech rozsvítil jeden jediný segment (a pak program zastavit nekonečnou smyčkou). Je možné že máš chybu v hardware a pak bys zbytečně ladil program. Postupuj od nejjednodušších úkolů a postupně přidávej (např. pak zobrazit jedinou číslici), než se snažit hned o hotový program, bez zkoušení mezikroků.

PORTD=znaky(int)(zobrazit/10)]; 

Takto nemůžeš číst z pole uloženého v paměti programu.

Místo

uint8_t PROGMEM znaky] = ...

použij

uint8_t znaky] = ... ... PORTD=znaky(zobrazit/10)] /vynech (int)

Další problém je že na portu C máš k dispozici jenom 6 pinů (sedmý je Reset). Jak tam chceš připojit 7 segmentů?
Pokud máš interní oscilátor, můžeš použít celý port B.

Častěji se ale používá časový multiplex
dhservis.cz/dalsi_1/popis_2.htm

Pro Colin, zde jsem zkusil něco naprogramovat, v reálném zapojení to bude asi ještě potřebovat tvarovač signálu mezi mag.čidlem a uprocesorem:
Tachometr.zip (35.9 KB)

Standa33: jen malá technická, jestli počítám dobře, tak by to mělo zvládnout měřit do 31250 hz po male úpravě?

Mě by zajímal ten tvarovač. Jak by to mohlo být realizováno?

Nemá mcu(např. Atmega328) na vstupech při interruptu s reakcí na hranu připojen schmitův KO?