Sida 1 av 2

Nixie-klocka

Postat: 25 december 2005, 22:07:31
av Virr3
Nu var de dax för mig med.
en nixieklocka alltså...

jag har inte kommit så jätte långt i utväcklingen av den just nu men det går sakta men säkert frammåt.

nåväl, lite har man allt hunnit med, jag har funderat mycket på hur den ska se ut, och har kommit fram till att den ska se ut i något i den här stilen,
Bild

Rören kommer troligen att bli in-2 eller in-4...

chassit ska byggas i ek tror jag... så det blir inte rikgit lika ljust som på bilden...


men, innan jag börjar att beställa massor med saker osv så vill jag bli färdig med koden. detta för att jag inte vill spendera massor med pengar utan att det blir något.

Hade tänkt att bygga den runt en ATMega32:a med en extärn klock-kristall och Timer2 för klockan...

har filat på koden nu ett tag men, jag är inte sådär jättebra på att programera så det går väldigt sakta frammåt, nåväl så här ser koden ut just nu.

Kod: Markera allt

#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

void strobe(void);
void strobe(void)
{
DDRC = _BV(PA0);
PORTC |=  _BV(PA0);
_delay_loop_1(10);
PORTC &= ~_BV(PA0);
}
void clock(void);
void clock(void)
{
DDRC = _BV(PA2);
PORTC |=  _BV(PA2);
_delay_loop_1(10);
PORTC &= ~_BV(PA2);
}
void data_ok(void);
void data_ok(void)
{
DDRC = _BV(PA1);
PORTC |=  _BV(PA1);
_delay_loop_1(10);
PORTC &= ~_BV(PA1);
}

void data_nej(void);
void data_nej(void)
{
_delay_loop_1(10);
}

void enable(void);
void enable(void)
{
DDRC = _BV(PA3);
PORTC |=  _BV(PA3);
_delay_loop_1(10);
PORTC &= ~_BV(PA3);
}

SREG = 0x80;   //Global interrupt enable
TCCR0 = 0x05;  //Aktivera "Normal mode"
ASSR = 0x08 ; //Asynchronous Timer/Counter2 Enable
TIMSK = 0x80;  //Timer/Counter2 Overflow Interrupt Enable 

int main(){


uint8_t Htio = 0;
uint8_t Hen = 0;
uint8_t Mtio = 0;
uint8_t Men = 0;
uint8_t Stio = 0;
uint8_t Sen = 0;
uint8_t data; 
uint8_t clock;
uint8_t cl;
uint8_t strobe;
uint8_t f=9;
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
uint8_t e;


SIGNAL (SIG_OVERFLOW2)//interuppt triggas på owerflow
{
	strobe(void);
	clock(void);	

}
asm volatile("sei");  //enable interrupt 
while(1)
{	enable(void);
	if(cl==1){Sen++}
	if(Sen>10)
	{	Sen=1;
		Stio++;
	}
	if(Stio==6)
	{
		Stio=0;
		Men++;
	}
	if(Men>10)
	{
		Men=0;
		Mtio++;
	}
	if(Mtio==6)
	{
		Mtio=0;
		Hen++;
	}
	if(Hen==10)
	{
		Hen=0;
		Htio++
	}
	if(Htio==2){Htio=0;}
}

if(f==9)
{
	for(a=0;a>9;n++)
	{
	   if(Htio==n)
	   {
		data();
	   }
	   
	   else
	   {
			data_nej();
			clock();
	   }
	}
}
if(a==9)
{
	for(b=0;b>9;n++)
	{
		f=0;
		if(Hen==n)
		{data_ok();}
		else
		{
			data_nej();
			clock();
		}
	}
}
if(b==9)
{
	for(c=0;n>9;c++)
	{
		if(Mtio==n)
		{data_ok();}
		else
		{
			data_nej();
			clock();
		}
	}
}
if(c==0)
{
	for(d=0;n>9;d++)
	{
		if(Men==n){data_ok();}
		else
		{
			data_nej();
			clock();
		}
	}
}
if(d==9)
{
	for(e=0;n>9;e++)
	{
		if(Stio==n){data_ok();}
		else
		{
		   data_nej();
		   clock();
	   }
	}
}
if(e==9)
{
	for(f=0;n>9;f++)
	{
	   if(Sen==n){data_ok();}
	   else
	   {
			data_nej();
			clock();
	   }
	}
}




problemet är att den kommer bara att stå och mala i första while loopen...

någon som vet hur jag löser detta och eventuellt andra fel i koden...

Ha de trevligt:) skulle vara jättesnällt ifall någon kunde ta sig en titt på koden...

Edit: lite tillagt. mest i koden...

Postat: 25 december 2005, 22:56:47
av PaNiC
I min kod har jag ordnat ett smidigt interrupt varje sekund som ökar sekunderna och utför resten av räkneoperationerna.
Resten av tiden står den bara och tuggar i en loop.

Visst, man kan ju göra som du har gjort också. Inget fel i det.

Personligen bygger jag hellre färdigt hårdvaran först och programmerar sedan just för att man kan testa koden, ändra, testa osv.
Även för att jag är bättre på hårdvara än mjukvara, något som gör att jag sorterar när jag ritar schema vilka saker som ska lösas i hårdvara och vilka som ska lösas i mjukvara. Dessutom tycker jag det är lättare att tänka mig bitar av koden medan jag ritar scheman och tänka efter om jag överhuvudtaget kan lösa det i mjukvara eller helt enkelt måste göra någon hårdvarugrej.

Förstår inte all kod, men kan inte se några direkta fel.

Postat: 26 december 2005, 00:07:42
av Virr3
anledningen till att jag gör mjukvaran först är att jag har en obehaglig vana att börja på saker som aldrig blir färdiga, så då tänkte jag iom att programeringen är gratis... att programera först å få de färdigt så är de bara de roliga kvar sen, att göra kretskortet och löda allt osv...

kanske kan man göra en egen funktion av den första while satsen, går den förbi då? eller stannar den där då ändå eller?

vilken del av koden förstår du inte? kanske kan jag förklara hur jag tänkt...

Postat: 26 december 2005, 12:09:15
av PaNiC
Jo jag har samma obehagliga vana. Mycket irriterande är det.
Du kan mycket väl göra en egen funktion av den första while-satsen. Antingen det eller istället köra "while(cl==1)"

Bland annat förstår jag inte detta riktigt..
Vid interrupt sätter du cl=1. Direkt därefter sätter du cl=0.
Sedan efter strobe så avslutar du kodblocket. Nu vet jag inte riktigt om det fungerar som jag tror eller inte, men körs verkligen while-satsen och därmed räknandet under tiden som cl==1?
Jag tror inte att den gör det.
Jag hade istället satt hela räknefunktionen i interruptet och sedan låtit den stå i en for(;;);-loop någon annanstans.

Såhär:


int main()
{
while(1)
{
//släng ut alla tidvariabler på rören här, detta behöver dock bara göras en gång om du använder 74141. Loopas om du kör multiplex.
}
}


Interrupt(owerflow2)//interuppt triggas på owerflow
{
Sen++;
if(Sen==10)
{ Sen=0;
Stio++;
}
if(Stio==6)
{
Stio=0;
Men++;
}
if(Men>10)
{
Men=0;
Mtio++;
}
if(Mtio==6)
{
Mtio=0;
Hen++;
}
if(Hen==10)
{
Hen=0;
Htio++
}
if(Htio==2){Htio=0;}
}


Har du tänkt att köra multiplex?
Jag gillar inte den idén, utan hade (och har ;) ) istället använt 74141 eller den ryska motsvarigheten K155ID1 BCD to terminal-decoders och drivit rören direkt.
Det går åt fler IO-pinnar (fyra per rör), men du slipper att hamna i tidsbrist eller något annat klammeri när det gäller tid. Mellan interrupten får du en hel sekund på dig att göra saker. Dessutom sägs det att rörens livslängd förkortas i multiplex.

Postat: 26 december 2005, 12:16:09
av Virr3
ne, någon multipex blir de inte...

några stycken 74HC4094 så ska jag kunna klara mig på 4pins till alla rören:)

ha det trevligt :)

Postat: 26 december 2005, 16:20:00
av Xyzzy
i dina for-loopar...
ex:

Kod: Markera allt

   for(b=0;b>9;n++) 
   { 
      if(Hen==n) 
      {data=1;} 
      else 
      { 
         datapin=0; 
         clock=1; 
         clock=0; 
      } 
   }
så är det ju 'n' som ökas men det är 'b' som kollas om den är rätt storlek (liknande förvirring finns i flera av for-looparna). Kanske ska vara så, men det ser inte korrekt ut.

Dessutom ser for-loopen ut som följer:
for (init; villkor; ändring)
Där "init" är vad en variabel är från loopens början (verkar vara korrekt i din kod).
Sedan sker "ändring" så länge som "villkor" är sant (dvs du borde ha, i ex. ovan, for(b=0;b<10;b++) om b ska loopa 10 ggr ('b' går mellan 0 och 9).

Postat: 26 december 2005, 18:49:20
av Virr3
ne, det är jag som missat den när jag kopierade upp alla loopar...

det ska givetvis vara b som ökar...

tack för att du såg de:) hade säkerligen missat de annars :)

Postat: 27 december 2005, 00:52:24
av B1n4ry
Du måste ju skicka klockpulsen till 4094:orna oavsett om det är en 1:a eller en 0:a som du skall skicka ut!

for(n=0;n>9;n++)
{
if(Hen==n)
{
data=1;
clock=1;
clock=0;
}
else
{
datapin=0;
clock=1;
clock=0;
}
}

eller ännu bättre (mindre kod)

for(n=0;n>9;n++)
{
if(Hen==n)
{
data=1;
}
else
{
datapin=0;
}
clock=1;
clock=0;
}

och så (kanske) lite delay mellan clock=1 och clock=0 (om det behövs)...

Att du sedan har dom där while(datapin==1) (och samma för clock) fattar jag inte..
På varje ställe där du i dina loopar sätter clock=1 eller 0 så sätt utpinnen hög respektive låg direkt. Hur det ser ut i c vet jag inte men du borde ju kunna definiera variabeln "clock" som en pekare rakt på pinnen!?

//B1n4ry

Postat: 9 januari 2006, 19:02:18
av Virr3
Har pillat lite till med koden, men ska kolla på de lite till :)

Idag fick jag rören jag kommer att använda:)

så, jag tog lite bilder på dem:)

De är av sorten IN-4 och är av den liggande sorten som ni förmodligen ser.

Bild
Bild
Bild
Bild
Bild
Bild
Bild
Bild

de är finare i verkligheten...

jag har heller inga grejer så att jag kan testa dem, men jag har pillat lite med ett schema nu och det bode vara färdigt imorgon eftermiddag om inte något oväntat händer, så då postar jag de väl här och ser vad ni tycker om de, och ifall jag ska göra några ändringar...

ha de så trevligt //Viktor

Postat: 10 januari 2006, 19:56:43
av Virr3
Nu är schemat så gott som färdigt:)

Bild
STOR

Postat: 10 januari 2006, 20:01:44
av jack
Bilden verkar inte funka.

Snygga rör förövrigt.
Ser fram emot bygget, försök dokumentera allt så grundligt som möjligt. Så man kan apa efter :)

Postat: 10 januari 2006, 20:05:20
av Virr3
Okej, jag ska skriva så mycket jag hinner och kan om bygget:)

om någon skulle vilja kolla på schemat skulle de vara snällt:) är inte 100 på att det funkar nämligen;)

Postat: 10 januari 2006, 21:43:34
av B1n4ry
Jag fick inte heller upp den stora versionen...
Men det jag lyckas tyda av den komprimerade bilden så ser det bra ut!

Påminner lite om min egen nixieklocka #1 ;-)

Fixar du den stora bilden så skall jag kika lite mera noga sedan!

//B1n4ry

Postat: 11 januari 2006, 00:38:07
av PaNiC
Får jag fråga varför du har valt en så stor µC när du bara använder 7 IO? :)

Vad är S5 till?
Linjerna går inte fram till anod-headern. Du måste dra dem till pinnarna.

Postat: 11 januari 2006, 07:29:27
av Virr3
http://stuffnet.1go.dk/schema.png

det funkar om man klistrar in i adressfältet, hoppas ja...

1.Man tager vad man haver;) så de får bli en atmega32:a

S5 är ifall jag vill stänga av rören men inte vill att den ska tappa tiden...
alltså en strömbrytare till anoderna till nixirören...

Vad menar du att linjerna inte går fram till anod-headern? anoderna till rören ska vara från kontakten där uppe?