Hojjalarm

Berätta om dina pågående projekt.
Användarvisningsbild
Macce
Inlägg: 4301
Blev medlem: 29 maj 2003, 16:40:58

Hojjalarm

Inlägg av Macce »

När jag nu fått igång min AVRprogrammerare och skrivit några enkla program mha instruktioner av forummedlemmarna, måste jag ju också göra något praktiskt.

Skall göra ett tjuvalarm till hojjen med en atTiny2313 och en vibrationssensor.

Mjukvaran skall kolla efter läget på vibrationssensorn, och vid behov pulsera 10 ggr med några pinnar -> blinkersen blinkar och tutan tutar.
För att hinna i lugn och ro parkera skall alarmet ha en fördröjning på 30sec före det aktiveras.

Påslagning och deaktivering av larmet har jag inte ännu bestämt mig på, men funderar på att ha ett relä som drar när man vrider på startlåset och bryter strömmen för larmet.
I startlåset finns det en ledning som får +12V när man vrider på, och en som blir - när man vrider av. Den som blir - kommer från CDIn (= tändningen stryps när man vrider av) så vet inte om AVR'n mår så bra av att ha den ikopplad som - så relät verkar bäst.

Det alarmet mest skall tjäna till är att skrämma iväg fjortisar som går och petar på hojjen

Vad tror ni om idén?

Koden jag har är en lite modifierad version av den jag fick som exempel i avrtråden jag skapade för en tid sedan. Det jag ännu inte fixat är fördröjningen på 30sec.

Hur skall jag beräkna basmotstånden till transistorerna som skall styra reläna? Har passligt många relän + trissor hemma så skulle gärna använda dom istället för att köpa fettar och ha dom att driva tutan/lamporna direkt.
Transistorerna jag tänkt använda är BC547 och reläna drar modiga 30mA styck.

Strömförsörjningen till hela alltihopa har jag tänkt lösa med en 7803a. Batteriet på hojjen är på 4.2A så standbytiden borde bli helt OK när jag kör flera gånger/vecka.
Fungerar det någotsånärbra med linjär regulering från 12V till 3V eller borde jag använda någon färdig switchad lösning för att minska värmeutvecklingen? Strömmen som AVRen drar i standby är ju inte så jättemycket.

Koden kommer snart...
Användarvisningsbild
Macce
Inlägg: 4301
Blev medlem: 29 maj 2003, 16:40:58

Inlägg av Macce »

koden:

Kod: Markera allt

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



int alarm()
 {
float i = 0;

for ( i= 0;i < 10; i++)
   {
    PORTB = 0x00;
    Delay_ms(150);
    PORTB = 0xFF;
    Delay_ms(150);
   }
 }



 int main()
{
    DDRB = 0xFF;
    PORTB = 0x00;

    DDRD = 0x00;
    PORTD = 0xFF;


    while (1)
    {





   if (!(PIND & _BV(PD3)))
        {
        alarm();
        }
        else
        {
            PORTB = 0x00;
        }



    }
Vibrationssensorn är alltså kopplad mellan - och PD3. Trissorna och reläna skall kopplas till utgångarna.

Det jag skulle vilja ha till denna kod är en 30sec fördröjning efter att avren får ström i sig. Skulle också vara trevligt med en lysdiod som blinkar med PB0 när alarmet inte är utlöst.

Edit: viive2.h innehåller koden för Delay_ms.
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

Jag kan noll om C-kompilatorn till AVR, men varför definerar du i som float?
float känns extremt overkill för en AVR att ha som räknare. Dessutom kan en IEEE-float inte inneha värdet 0.
Förövrigt känns det som 150ms mellan av/påslag kanske känns lite kort?
300-400 kanske mer lämpligt?

Mvh
speakman
Användarvisningsbild
Macce
Inlägg: 4301
Blev medlem: 29 maj 2003, 16:40:58

Inlägg av Macce »

Kan som sagt väldigt lite C, och ända typen jag kom ihåg från Cböckerna var float så därav det :D Det är som sagt ett av mina första projekt.

Tiden får jag ställa när jag testat hur det blir. Tror 150ms känns psykiskt längre än vad det är för den som utlöser alarmet.
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Byt ut float mot uint8_t (kan innehålla ett tal mellan 0 och 255).

För att få en fördröjning i början är det bara att lägga in en tillräckligt lång väntan innan du går in i while-loopen. Jag vet inte hur du som längst kan vänta med den där Delay_ms()-funktionen du använder. Men kan du inte vänta i 30 sekunder genom Delay_ms(30000) så får du gör flera mindre delays som förslagsvis lägger i en loop.

typ,

Kod: Markera allt

uint8_t i;
for (i=0;i<100;i++)
    Delay_ms(300);
För att få ett "statusblink" en gång i sekunden så löser du nog det enklast med en timer.

Prova den här koden. Vet inte om den fungerar. Men prova att sätt en lysdiod på PB0 och se om det händer något. Kan förklara mer sen.

Kod: Markera allt

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

#define STATUSBLINK_WAIT_DELAY 49911
#define STATUSBLINK_BLINK_DELAY 63973

#define STATE_STATUSBLINK_WAIT 0
#define STATE_STATUSBLINK_BLINK 1

int alarm()
{
	uint8_t i = 0;

	for (i=0; i<10; i++)
	{
		PORTB = 0x00;
		Delay_ms(150);
		PORTB = 0xFF;
		Delay_ms(150);
	}
}

int main()
{
	uint8_t statusblink_state = STATE_STATUSBLINK_WAIT;
	
	DDRB = 0xFF;
	PORTB = 0x00;

	DDRD = 0x00;
	PORTD = 0xFF;

	TCNT1 = STATUSBLINK_WAIT_DELAY; // Laddar startvärdet i timern
	TCCR1B = _BV(CS12); // Ställer in 16-bitarstimern med en prescaler på /256

	while (1)
	{
		if (!(PIND & _BV(PD3)))
		{
			alarm();
		}
		else
		{
			PORTB = 0x00;
		}

		if (TIFR & _BV(TOV1)) // En overflow har skett
		{
			if (statusblink_state == STATE_STATUSBLINK_WAIT)
			{
				TCNT1 = STATUSBLINK_BLINK_DELAY;
				statusblink_state = STATE_STATUSBLINK_BLINK;
				PORTB |= _BV(PB0);
			}
			else
			{
				TCNT1 = STATUSBLINK_WAIT_DELAY;
				statusblink_state = STATE_STATUSBLINK_WAIT;
				PORTB &= ~_BV(PB0);
			}

			TIFR |= _BV(TOV1); // Nollställer overflow-flaggan
		}
	}

	return 0;
}
Användarvisningsbild
Macce
Inlägg: 4301
Blev medlem: 29 maj 2003, 16:40:58

Inlägg av Macce »

Tack för koden, men den verkar inte göra mycket annat än min kod.

Fördröjningen fungerar ej, och PB0-lysdioden blinkar inte heller.
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Fördröjningen är inte inlagd i den koden.

Kan kolla koden lite senare idag.
Användarvisningsbild
Macce
Inlägg: 4301
Blev medlem: 29 maj 2003, 16:40:58

Inlägg av Macce »

Okej. Tackar på förhand :)
Användarvisningsbild
Macce
Inlägg: 4301
Blev medlem: 29 maj 2003, 16:40:58

Inlägg av Macce »

Startdelayn fick jag fixat med att lägga Delay_ms(3000) före whileloopen i main.

Hur skall jag bäst fixa så att PD0 växlar med typ 1sec mellanrum mellan etta och nolla?
Har en lösning, men det gör att den pausar funktionen på larmet varannan sekund, vilket inte är så bra :)

Motstånden till trissorna då, hur skall jag räkna dem?
Jag skulle tro att ganska många skulle ha nytta av det om någon skulle skriva en liten guide angående hur man skall räkna.
Trissorna är BC547B och skall drivas från pinnar på avren. Reläna drar 30mA om det har någon betydelse.
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Jag har nu testat min kod på en Mega48 och blinkfunktionen fungerar precis som den ska. Säker på att du har kopplat lysdioden rätt från PB0?

Det blir inget snyggt om lysdioden växlar mellan på och av varje sekund. Det blir snyggare om den blinkar till under ett kort ögonblick varje sekund istället. Det är det min kod gör.

Kolla i databladet till BC547B så ser du att den i värsta fall bara förstärker 200 ggr. Kolla även i Ic-Hfe-diagrammet för Ic=30mA så ser du att förstärkningen ligger där någonstans även för Ic=30mA. Som du ser så minskar förstärkningen när Ic ökar. För Ic=30mA måste du minst mata strömmen 30mA/200=0.15mA genom basen (Ibe). Spänningsfallet Ube (spänningen mellan basen och emittern) är som lägst 0.58V. Ska du styra transistorn med en 3V-signal från AVR:en kommer det ligga 3-0.58V=2.42V över basmotståndet. Ohms lags ger att R=2.42/0.15=16kOhm. Välj ett motstånd mindre än 16 kOhm.
Användarvisningsbild
Macce
Inlägg: 4301
Blev medlem: 29 maj 2003, 16:40:58

Inlägg av Macce »

Provade koden på experimentplattan före jag lödde ihop det på veroboard.
PB0 var av hela tiden.

Testade med ett motstånd på 1k. Relät drar 2 gånger, sedan händer inget mer. Mäter jag mellan mellan ermitter och collector får jag ca 2.5V. Har jag för litet/stort motstånd?
Användarvisningsbild
Schnegelwerfer
Inlägg: 1863
Blev medlem: 8 november 2004, 13:46:56

Inlägg av Schnegelwerfer »

Glöm inte frihjulsdioden över relät! Om man inte kopplar en diod "bakvänt" över reläspolen, kommer det dödliga spänningsspikar (i alla fall för elektroniken :wink: ) när transistorerna bryter.

Det är stor risk att du bränt transistorerna om du inte kopplat in dessa dioder.

Angående basmotstånd så tycker jag att det bästa är att fläska på ordentligt med basström, så att man säkert vet att transistorn bottnar. Du kan t.ex. räkna på ett minsta Hfe på 10-50, och en Ube på 0,7V.

3V utspänning från AVR:en, Ube = 0,7V samt Hfe = 50 ger en basström på 0,6mA (vid 30mA reläström). Spänningsfallet över basresistorn blir nu 3-0,7 = 2,3V. Basresistorn blir 2,3/0,0006 = ~ 3,9k

Detta resonemang förutsätter att transistorns emitter är kopplad till jord, och emittern till den "negativa" sidan av relät.
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Macce skrev:Provade koden på experimentplattan före jag lödde ihop det på veroboard.
PB0 var av hela tiden.

Testade med ett motstånd på 1k. Relät drar 2 gånger, sedan händer inget mer. Mäter jag mellan mellan ermitter och collector får jag ca 2.5V. Har jag för litet/stort motstånd?
Provade du med en lysdiod från PB0 till jord? Mäter du med digital multimeter är det inte säkert att den hinner registrera blinket. För att felsöka lite; lägg in raden "PORTB |= _BV(PB0);" på raden innan "TIFR |= _BV(TOV1);". När du kör programmet ska lysdioden iaf tändas.

Det vore bra om du ritade ett schema på hur du har kopplat reläet till AVR:en, så att det inte uppstår några missförstånd pga det.
Användarvisningsbild
Macce
Inlägg: 4301
Blev medlem: 29 maj 2003, 16:40:58

Inlägg av Macce »

cykze, japp, på experimentplattan/programmeraren jag har (denna), finns det lysdioder till alla portarna, och ingen lysdiod blinkade när alarmet inte var utlöst, men alla börjar blinka när alarmet utlöses (som det är meningen).

En diod över trissan har jag nog.


Bild på kopplingen:


Bild
Användarvisningsbild
Schnegelwerfer
Inlägg: 1863
Blev medlem: 8 november 2004, 13:46:56

Inlägg av Schnegelwerfer »

Aha!

Dioden ska kopplas direkt över reläet, och inte till transistorns emitter som på ditt schema. Som det är kopplat nu skyddar dioden inte mot spänningsspiken som uppkommer när reläet bryter.

Storleken på basmotståndet är helt ok, det skall fungera.

Jag förstod inte riktigt vad du hade för problem. Fungerade reläet 2 ggr, och sedan aldrig mer? I så fall tror jag att du bränt transistorn.
Skriv svar