Spaceshuttle-Countdown für C-Control Pro Mega128 gesucht

von Schnitzel

Captain
Registriert
Apr. 2008
Beiträge
3.903
Hi Leute,

es fällt mir echt schwer um so was zu bitten, aber da meine letzte Basicstunde nun schon über 12 Jahre her ist ..., suche ich für ein Casecon-Thema einen Basic oder C-Compact Code für das C-Control Pro mit dem Mega128 mit Tastatur und Display von Conrad (als einziges z.Z. im nächsten Geschäft auf Lager).
Und zwar soll es ein Countdown sein, wie man ihn beim beim Start eines Spaceshuttle sehen kann, der bei Null einen Kontakt kurz schließt (PC-Start) und dann weiter zählt.
Per Tastatur soll der "negative" Startwert eingegeben werden, und per Tastendruck auf Switch1 gestartet.
Ich habe schon alle Seiten abgesucht, die mir eingefallen sind. Bevor ich mich jetzt noch in einem anderen Forum anmelde, wollte ich erst hier fragen, ob mir jemand bei meinem Problem helfen kann.

Schonmal Danke im Voraus für eure Hilfe.
 
von Schnitzel schrieb:
der bei Null einen Kontakt kurz schließt (PC-Start) und dann weiter zählt.

Hört sich an, als ob du eine Bombe bauen willst :)
 
Wieso wusste ich nur, dass dieser leidige Satz kommt.

Da würde es aber keinen Sinn machen, nach der Null weiterzuzählen.
 
Welcher Kontakt soll denn kurzgeschlossen werden und für wie lange?

Edit:
Wie soll der Countdown formatiert sein und wo sollen die Grenzen liegen?
HH:MM:SS oder soll der Countdown länger laufen, so dass Tage auch benötigt werden?

Gruß
BlackMark
 
Zuletzt bearbeitet:
Hi,

ich meinte kurz geschlossen (wie in "den Kontakt schließen") für ca. eine Sekunde; kein Kurzschluss^^.

Für den Effekt sollte HH:MM:SS langen (auch wenn nur Sekunden langen würden, den länger will ich nicht warten bis der PC startet^^).
Ich muss zugeben, über die Grenzen hab ich noch nicht nachgedacht; aber ich schätze, dass es bis "T+10" Minuten langen würde. Selbst wenn er einen ganzen Tag zählen würde - sprich alle stellen bis zum Maximum - wäre auch egal, da das ganze mittels der Resetknöpfe neugestartet werden kann.
Tage wären dann doch zuviel.

P.S.
Danke für deine Hilfe
 
von Schnitzel schrieb:
ich meinte kurz geschlossen (wie in "den Kontakt schließen") für ca. eine Sekunde; kein Kurzschluss^^.
Den Kontakt schließen = Kurzschluss! Ich wollte aber wissen für wie lange du den Kontakt geschlossen haben willst und welcher Pin dafür verwendet werden soll? Wie genau verbindest du das C-Control Board mit deinem Mainboard?

Mein momentaner Code erlaubt einen Countdown von -99:59:59 ( also mehr als 4 Tage ) bis +99:59:59. Sollte also für dich ausreichend sein. Was soll denn bei erreichen des Limits passieren? Soll der Zähler stoppen oder wieder bei 0 anfangen?

Gruß
BlackMark
 
Von Port A sollte Pin 0 und Pin 1 für eine Sekunde geschlossen werden.
Da die Ports unter Spannung stehen, werde ich mittels Optokopplerschaltung ein 3,5 Volt Relai (hab ich noch rumliegen) schließen lassen, welches dann das Drücken des Einschaltknopfes darstellt.

Wenn der Countdown das Limit erreicht hat, soll er stoppen.
 
Ich habe ein bisschen experimentiert und es geschafft den PC nur durch die Pins des C-Control Boards einzuschalten, du brauchst also kein Relais und auch keine Optokopplerschaltung.

Im Anhang findest du das Projekt bzw. hier ist der gesamte Code:
Code:
/*
 * Copyright (c) by BlackMark 2013
 * Date 27/05/2013
 * Version 1.3
 *
 * Used Ports: SW1, SW2, PortA.6, PortA.7
 * Used Periphery: 3x4 Keyboard, 2x8 LCD
 * Used Libraries: IntFunc_Lib.cc, Key_Lib.cc, LCD_Lib.cc
 * Purpose: Initialize a countdown through the 3x4 keyboard. The keys '*' and '#' move the cursor left and right.
 *          SW1 starts the countdown and SW2 exits the program.
 *          Once the countdown has reached 0 it turns PortA.7 on for 1 second and starts counting upwards until 99:59:59 at which point it stops.
 */

#define PORT_A6 6
#define PORT_A7 7

long g_lSecondCounter;
byte g_bStartCounter;
char g_szLCDText[9];

void CounterToLCDText( void )
{
	long lPositiveSecondCounter;
	byte byteHour;
	byte byteMinute;
	byte byteSecond;

	lPositiveSecondCounter = ( (g_lSecondCounter < 0) ? (-g_lSecondCounter) : (g_lSecondCounter) );

	byteHour = lPositiveSecondCounter / 3600;
	byteMinute = lPositiveSecondCounter / 60 - byteHour * 60;
	byteSecond = lPositiveSecondCounter - byteMinute * 60 - byteHour * 3600l;

	Str_Printf( g_szLCDText, "%02d:%02d:%02d", byteHour, byteMinute, byteSecond );
}

void DisplayTime( byte byteStartCursorPos, byte byteEndCursorPos )
{
	LCD_CursorPos( byteStartCursorPos );
	LCD_WriteText( g_szLCDText );
	LCD_CursorPos( byteEndCursorPos );
}

void ProcessKeyboard( void )
{
	static char s_chKeyOld;
	static char s_chCursorPos;
	word wKey;
	char chKey;
	
	wKey = Key_Scan();
	
	if( wKey )
	{
		chKey = Key_TranslateKey( wKey );

		if( chKey != s_chKeyOld )
		{
			s_chKeyOld = chKey;

			if( chKey == '*' )
			{
				--s_chCursorPos;

				if( s_chCursorPos == 2 ||  s_chCursorPos == 5 )
				{
					--s_chCursorPos;
				}
			}
			else if( chKey == '#' )
			{
				++s_chCursorPos;

				if( s_chCursorPos == 2 || s_chCursorPos == 5 )
				{
					++s_chCursorPos;
				}
			}
			else
			{
				g_szLCDText[s_chCursorPos] = chKey;

				++s_chCursorPos;
			}

			if( s_chCursorPos == 2 || s_chCursorPos == 5 )
			{
				++s_chCursorPos;
			}

			if( s_chCursorPos < 0 )
			{
				s_chCursorPos = 0;
			}

			if( s_chCursorPos > 7 )
			{
				s_chCursorPos = 7;
			}

			DisplayTime( 0, s_chCursorPos );
		}
	}
	else
	{
		s_chKeyOld = 0;
	}
}

// Timer2 gets called every 10ms
void Timer2Callback( void )
{
	static int s_iTickCounter;
	static byte s_bStopCounter;
	static byte s_bPortState;
	static byte s_bSignaled;
	
	if( !g_bStartCounter )
	{
		ProcessKeyboard();
	}
	else
	{
		++s_iTickCounter;

		if( g_lSecondCounter == 0 && !s_bSignaled )
		{
			if( !s_bPortState )
			{
				Port_WriteBit( PORT_A7, PORT_ON );

				s_bPortState = true;
			}
		}
		else
		{
			if( s_bPortState )
			{
				Port_WriteBit( PORT_A7, PORT_OFF );

				s_bPortState = false;
				s_bSignaled = true;
			}
		}
		
		if( s_iTickCounter == 10 )
		{
			CounterToLCDText();

			if( g_lSecondCounter < 0 )
			{
				DisplayTime( 0, 0 );
			}
			else if( g_lSecondCounter == 0 )
			{
				DisplayTime( 0, 0 );
				DisplayTime( 0x40, 0x40 );
			}
			else
			{
				DisplayTime( 0x40, 0x40 );
			}
		}

		if( s_iTickCounter == 100 && !s_bStopCounter )
		{
			g_lSecondCounter = g_lSecondCounter + 1;
			
			if( g_lSecondCounter > 359999 )
			{
				g_lSecondCounter = 0;
				s_bStopCounter = true;
			}

			s_iTickCounter = 0;
		}
	}

	Irq_GetCount( INT_TIM2COMP );
}

void main( void )
{
	byte byteSW1;
	byte byteSW2;

	char szBuffer[3];
	byte byteHour;
	byte byteMinute;
	byte byteSecond;

	g_lSecondCounter = 0;
	g_bStartCounter = false;
	g_szLCDText = "00:00:00";
	szBuffer = "00";

	LCD_Init();
	LCD_ClearLCD();
	LCD_CursorOn();
	LCD_CursorPos( 0 );
	LCD_WriteText( g_szLCDText );
	LCD_CursorPos( 0 );

	Key_Init();

	Port_DataDirBit( PORT_SW1, PORT_IN );
	Port_DataDirBit( PORT_SW2, PORT_IN );
	Port_WriteBit( PORT_SW1, PORT_OFF );
	Port_WriteBit( PORT_SW2, PORT_OFF );

	Port_DataDirBit( PORT_A6, PORT_IN );
	Port_DataDirBit( PORT_A7, PORT_OUT );
	
	Port_WriteBit( PORT_A7, PORT_OFF );
	
	Irq_SetVect( INT_TIM2COMP, Timer2Callback );

	while( true )
	{
		byteSW1 = Port_ReadBit( PORT_SW1 );
		byteSW2 = Port_ReadBit( PORT_SW2 );

		if( !byteSW1 && !g_bStartCounter )
		{
			szBuffer[0] = g_szLCDText[0];
			szBuffer[1] = g_szLCDText[1];

			byteHour = Str_ReadInt( szBuffer );

			szBuffer[0] = g_szLCDText[3];
			szBuffer[1] = g_szLCDText[4];

			byteMinute = Str_ReadInt( szBuffer );

			szBuffer[0] = g_szLCDText[6];
			szBuffer[1] = g_szLCDText[7];

			byteSecond = Str_ReadInt( szBuffer );

			g_lSecondCounter = -( byteHour * 3600l + byteMinute * 60 + byteSecond );

			if( g_lSecondCounter < -359999 )
			{
				g_lSecondCounter = -( 99 * 3600 + 59 * 60 + 59 );
			}

			LCD_CursorOff();

			g_bStartCounter = true;
		}

		if( !byteSW2 )
		{
			LCD_CursorPos( 0 );
			LCD_CursorOff();
			LCD_ClearLCD();

			break;
		}
	}
}

Durch * und # kannst du den Cursor verschieben. SW1 startet den Countdown und SW2 beendet das Programm.
PortA.6 fungiert als GND und PortA.7 ist dein PowerSW. Einfach die zwei Pins vom Mainboard mit PortA.6 und PortA.7 verbinden, falls es nicht geht hast du sie wahrscheinlich falsch herum angeschlossen.
Wie vorher schon erwähnt läuft der Countdown von -99:59:59 bis +99:59:59 und beim erreichen des oberen Limits wird alles auf 0 zurückgesetzt und der Countdown bleibt stehen. Der Pin wird jedoch nicht noch einmal geschlossen. ( Das würde nämlich den PC ausschalten )

Ich hoffe es entspricht deinen Vorstellungen und funktioniert bei dir auch so wie bei mir.

Gruß
BlackMark
 

Anhänge

Vielen Dank BlackMark.^^
Vielen, vielen, vielen Dank.
Entspricht vollkommen meinen Vorstellungen und ich bin mir ganz sicher, dass er prima läuft.
Und danke für deine Mühe bei der Pinbelegung.
 
von Schnitzel schrieb:
Vielen Dank BlackMark.^^
Vielen, vielen, vielen Dank.
Wenn ich schon einen C-Control Pro Mega128 herumliegen habe, den ich so gut wie nicht verwende, kann ich auch gleich so ein kleines Projekt umsetzen. Wäre doch schade, wenn das gute Ding nur Staub fängt ;)

von Schnitzel schrieb:
Ich bin mir ganz sicher, dass er prima läuft.
Das solltest du testen, vorher wäre ich mir da nicht so sicher.

von Schnitzel schrieb:
Und danke für deine Mühe bei der Pinbelegung.
Irgendwie muss ich ja feststellen, ob mein Programm das tut, was es soll und da ich kein Relais bei der Hand hatte, habe ich es eben direkt versucht, was zumindest bei mir auch wunderbar funktioniert hat.

BTW: Habe den Countdown mal für ca. 20 Stunden laufen lassen und gleichzeitig mit meiner Armbanduhr gestoppt. Nach den 20 Stunden geht der Countdown ca. 1 Sekunde vor, was eine recht annehmbare Genauigkeit ist, wie ich finde.

Gruß
BlackMark
 
Ich hatte mir das Board gekauft, da ich dachte, dass ich mit meinen noch vorhandenen Kenntnissen einen der Beispielcodes abändern könnte - was dann aber leider nicht der Fall war.
Vorher hatte ich mich - nachdem ich einige Videos auf YT angeschaut hatte - nach einem Schaltplan für eine hardwarebasierte Lösung ohne Programmierung umgesehen, jedoch leider vergebens - zumindest auf keiner für mich vertrauenswürdigen Seite. Das einzige, was ich in der Zeit in den ganzen Foren gelesen hatte, war eben, dass es doch so einfach ginge mit einem MC.

Zum testen komme ich arbeitsbedingt leider erst Morgen.

Von der Genauigkeit her, klingt das sogar richtig gut.
 
von Schnitzel schrieb:
Ich hatte mir das Board gekauft, da ich dachte, dass ich mit meinen noch vorhandenen Kenntnissen einen der Beispielcodes abändern könnte - was dann aber leider nicht der Fall war.
Bei den Beispielen ist soweit ich weiß kein brauchbarer Countdown dabei, zumindest habe ich beim kurzen durchklicken nichts gefunden. Außerdem müsstest du mehrere Beispiele kombinieren, um alle deine gewünschten Funktionen zu erhalten, was schwer sein dürfte, wenn man nicht genau weiß, was der Code macht, den man vor sich hat.

von Schnitzel schrieb:
Vorher hatte ich mich - nachdem ich einige Videos auf YT angeschaut hatte - nach einem Schaltplan für eine hardwarebasierte Lösung ohne Programmierung umgesehen, jedoch leider vergebens - zumindest auf keiner für mich vertrauenswürdigen Seite. Das einzige, was ich in der Zeit in den ganzen Foren gelesen hatte, war eben, dass es doch so einfach ginge mit einem MC.
Interessant. Wobei ich mir vorstellen kann, dass ein rein hardwarebasierter Countdown unglaublich schwer umzusetzen sein muss. Das geht auf jeden Fall mit einem µController viel leichter.

von Schnitzel schrieb:
Zum testen komme ich arbeitsbedingt leider erst Morgen.
Kein Problem. Gib mir dann bescheid ob alles so funktioniert wie du es haben willst und ob du gegebenenfalls Änderungen oder Erweiterungen haben möchtest.

von Schnitzel schrieb:
Von der Genauigkeit her, klingt das sogar richtig gut.
Nicht wahr? Ich war auch positiv überrascht, dass der Countdown so genau ist. Ich habe eigentlich keinerlei Arbeit in die genaue Programmierung des Timers investiert; ich hätte mir eigentlich erwartet, dass ich nachträglich noch Optimierungen durchführen müsste, um den Countdown halbwegs genau zu bekommen, aber der Mega128 ist scheinbar sehr zuverlässig, wenn es um Timer geht. ( Nach 44 Stunden geht der Countdown nun um ca. 1.5 Sekunden vor )

Gruß
BlackMark
 
Hi,
ich hab gerade mal testen wollen, scheine aber etwas falsch zu machen, da die Tastatureingaben nicht angezeigt werden bzw. nach dem vierten Tastendruck nur Streifen angezeigt werde.
Ich kann mir jedoch nicht vorstellen, was ich falsch mache. Ich öffne das Projekt, kompiliere es, übertrage es und starte.

DSC00449.jpg
 
Siehst du, deshalb habe ich gesagt du musst es testen, bevor du sagst du bist dir sicher, dass es laufen wird ;)

Mal sehen, du hast mein angehängtes Projekt genommen? Deine C-Control Pro IDE ist Version 2.13.0.15?
Du überträgst das Programm über USB? Deine Tastatur zeigt nach oben, wenn das Kabel wie in deinem Bild liegt?
Dein LCD zeigt nach unten, wenn das Kabel parallel zu dem der Tastatur liegt?
Deine Jumper sind so gesetzt wie bei mir? ( Außer der Jumper, der die Stromquelle regelt, denn wie ich sehe verwendest du das USB Kabel als Stromquelle )

Wird am Anfang 00:00:00 angezeigt und dein Cursor ist ganz links?
Was passiert wenn du * bzw. # drückst?
Wenn du eine Zahl eingibst passiert einfach gar nichts und nach dem vierten Mal wird nur Blödsinn ausgegeben, oder?

Gruß
BlackMark
 

Anhänge

  • IMG_1227.jpg
    IMG_1227.jpg
    577,8 KB · Aufrufe: 147
Zuletzt bearbeitet:
BlackMark schrieb:
Siehst du, deshalb habe ich gesagt du musst es testen, bevor du sagst du bist dir sicher, dass es laufen wird ;)

Ich hätte es auf jeden Fall getestet.

BlackMark schrieb:
Mal sehen, du hast mein angehängtes Projekt genommen?

Ja, das angehängte.

BlackMark schrieb:
Deine C-Control Pro IDE ist Version 2.13.0.15?

Ja, ist sie. Info IDE.jpg Info HW.jpg

BlackMark schrieb:
Du überträgst das Programm über USB?
Deine Tastatur zeigt nach oben, wenn das Kabel wie in deinem Bild liegt?
Dein LCD zeigt nach unten, wenn das Kabel parallel zu dem der Tastatur liegt?

Ja. DSC00453.JPG

BlackMark schrieb:
Wenn du eine Zahl eingibst passiert einfach gar nichts und nach dem vierten Mal wird nur Blödsinn ausgegeben, oder?

Genau das.

BlackMark schrieb:
Wird am Anfang 00:00:00 angezeigt und dein Cursor ist ganz links?

Nein, am Anfang ist nichts zu sehen. Kein Cursor, gar nichts.



BlackMark schrieb:
Deine Jumper sind so gesetzt wie bei mir?

Leider nicht. Werde ich, nach diesem Post korrigieren.

Bin gleich wieder da.

Bin wieder da.
hab nur zwei Unterschiede gefunden.
1) JP4 ist wg. der Stomzufuhr anders gejumpert. Mein Board bekommt den Strom vom USB-Anschluss (noch).
2) beim (unteren JP4) J4 ist bei dir ein Jumper drin und bei mir nicht. Brauche ich den auch, oder ist der auch nur für die Stromversorgung?
 
Zuletzt bearbeitet:
von Schnitzel schrieb:
Ich hätte es auf jeden Fall getestet.
Schon klar, ich bezog mich nur auf deine Aussage "Ich bin mir ganz sicher, dass er prima läuft." welche ja nun falsch ist ;)

IDE und das Ganze sieht gut aus.

von Schnitzel schrieb:
Nein, am Anfang ist nichts zu sehen. Kein Cursor, gar nichts.
Das bedeutet schon mal, dass das Programm von Anfang an nicht richtig läuft.

von Schnitzel schrieb:
beim (unteren JP4) J4 ist bei dir ein Jumper drin und bei mir nicht. Brauche ich den auch, oder ist der auch nur für die Stromversorgung?
Der ist laut Dokumentation für das zweite serielle Interface ( keine Ahnung wo das sein soll ) gedacht, sollte also irrelevant sein, aber teste trotzdem mal was passiert wenn du den Jumper genau wie bei mir setzt. Falls du keinen Jumper hast nimm einen vom Port E, die haben soweit ich weiß keinen Nutzen.

Ich schreibe mal ein kleines Testprogramm um zu sehen was bei dir nicht funktioniert. Ich tippe mal auf das LCD, aber wir werden sehen...

Edit: Versuch mal das Programm im Anhang!

Gruß
BlackMark
 

Anhänge

Zuletzt bearbeitet:
Das Jumpern hat nichts bewirkt.

Hab das Testprogramm durchlaufen lassen.
Nach 5120ms wurde der Interpreter gestoppt und auf dem Display war folgendes zu sehen:
DSC00454.JPG
 
Hab ich mir gedacht. Es ist das Display, das nicht funktioniert. Die Frage ist nur warum und wie kann man es reparieren?!

Teste mal eines der Beispiele. Bei den Beispielen sollte ein Ordner LCD mit einigen Beispielen darin sein, nimm LCD_1 und teste was passiert.

Gruß
BlackMark
 
Bei LCD_1.cc wird alles korrekt angezeigt; es sei denn, die ganz linke "0" gehört da nicht hin.
DSC00455.JPG

Edit:

Auch andere Beispielprogramme laufen ohne Darstellungsbehler.
z. B. LCD_Key; jede Tastatureingabe wird korrekt wiedergegeben.

Könnte die Art der Stomversorgung vllt. doch mehr beeinflussen?
 
Zuletzt bearbeitet:
Die ganz linke '0' gehört da nicht hin. Außerdem sollte der Cursor nicht angezeigt werden.

Steck mal das LCD komplett ab, schalte das Board aus und warte ein paar Sekunden. Dann steck alles wieder an und versuch LCD_2, da wird nämlich das LCD und das Keyboard verwendet.

Edit: Naja, das bei LCD_1 ist aber ein Darstellungsfehler! Mach trotzdem mal das was ich oben geschrieben habe.

Könnte die Art der Stomversorgung vllt. doch mehr beeinflussen?
Glaube ich nicht, warte ich teste das mal bei mir nur über USB Strom.

Edit2: Also bei mir funktioniert alles genau gleich auch über USB Strom.

Gruß
BlackMark
 
Zuletzt bearbeitet:
Zurück
Oben