PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programmierproblem



taylor22
25.06.2007, 16:30
hallo! kann mir jemand vielleciht weiterhelfen und sagen weshalb das nicht funktioniert: möchte über die serielle schnittstelle ein zeichen schicken, das dann eine LED einschaltet!

// Hauptprogramm
int main(void) {
Init();
unsigned char *buffer;

while(1){
SerRead(buffer,1,0);
if (buffer[0]=='1') {StatusLED(RED);}
else{BackLED(ON,ON);}
}

while(1);
return 0;
}

zumgwadrad
25.06.2007, 16:38
Hi,
ich glaub die Anführungszeichen müssen weg also:


if (buffer[0]==1)
anstatt
if (buffer[0]=='1')

taylor22
25.06.2007, 16:48
danke für die schnelle antwort, aber das wars leider nicht!

datobbs
25.06.2007, 19:18
// Hauptprogramm
#include "asuro.h"

int main(void)
{
Init();
unsigned char buffer [1];

while(1)
{
SerRead(buffer,1,0);
if (buffer[0]==1) {StatusLED(RED);}
else{BackLED(ON,ON);}
}

return 0;
}


Hi taylor22,

bin auch grad erst am anfangen,
wenn das wirklich alles ist, hast du vergessen die asuro.h bibliothek zu includieren.
ich würde die anführungszeichen auch weglassen, die brauchst du nur bei text würd ich sagen.
die buffer variable würd ich so wie oben (in meinem code) definieren das mim stern brauchst du glaub ich nur bei funktionen definieren.
des 2. while(1) kannst du dier sparen des erste is ja schon die endlosschleife.

kanns leider nich ausprobieren, bei meinem asuro hab ich irgendwie die batteriehalterung gekillt/geschmolzen

gruß tobi

taylor22
25.06.2007, 20:45
asuro.h habe ich schon inkludiert! die anführungszeichen habe ich weg genommen, und das zweite while(1) stört eigentlich nicht!
geht leider immer noch nicht!

datobbs
25.06.2007, 21:02
also so wie der code oben bei mir drinne steht muckt der compiler nicht,
muss genau auf die deklaration von den variablen achten klammern semikolon etc.

leider kann ichs immer noch nicht testen asuro geht wieder, aber es flashen tut nicht...

mfg

SlyD
25.06.2007, 22:04
Nicht getestet - aber probiers mal so:



unsigned char buffer[16]; // mit dem * deklarierst Du nur nen Pointer - Du
// brauchst aber nen Array! Hier mit 16 Zeichen...

// Hauptprogramm
int main(void) {
Init();

while(1){
SerRead(buffer,1,0);
if (buffer[0]=='1') {StatusLED(RED);}
else{BackLED(ON,ON);}
}

while(1);
return 0;
}


Ach und die Anführungszeichen müssen da hin - Du willst ja das Zeichen '1' empfangen ...

MfG,
SlyD

taylor22
25.06.2007, 23:49
super danke, so klappts! prima!

ehenkes
25.06.2007, 23:59
Wenn Du das Thema "Arrays und Pointer" vertieft verstehen willst:
http://www.henkessoft.de/C++/C/arrays_pointer.htm

taylor22
26.06.2007, 11:24
nächste Frage: weiss jemand, was hier noch fehlt oder was falsch ist? Sobald ich eine Taste auf der Tastatur drücke, sollte die StatusLED rot leuchten- eigentlich! Vielen Dank für Eure Hilfe!

ISR(USART_RXC_vect){
StatusLED(RED);
}

// Hauptprogramm
int main(void) {
Init();
StatusLED(OFF);
unsigned char buffer [16];
sei();
UCSRB|=(1<<RXCIE);
while(1)
{
SerRead(buffer,1,0);
}

return 0;
}

damaltor
26.06.2007, 13:53
leite mal die ISR so ein:

SIGNAL (USART_RXC){
...
}

taylor22
26.06.2007, 14:05
nein das ist es leider nicht! SIGNAL ist veraltet, neu schreibt man ISR und den Interrupt vektor USART_RXC gibt es nicht, der heisst USART_RXC_vect!

damaltor
26.06.2007, 14:51
naja lieber veraltet als nicht funktionierend...

im datenblatt steht USART_RXC als name. probiere es doch, wenns nciht geht kannste immer noch weiter suchen...

taylor22
26.06.2007, 15:18
habs probiert geht nicht!
warning: 'USART_RXC' appears to be a misspelled signal handler

damaltor
27.06.2007, 13:04
mmh... dann weiss ich spontan auch nich weiter... ;)

inka
29.06.2007, 14:17
ich weiss nicht wo ich mein "problem" unterbringen soll - also unter "programmierproblem" ist ja wohl richtig :-)
Der asuro soll schauen, ob vor ihm platz ist (ultraschall), eine strecke fahren, 90grad abbiegen und erstmal stehen bleiben. Ich komme einfach nicht dahinter warum er die abfrage nach der entfernung (if(abstand > 25)) überspringt und nicht geradeuasfährt, sondern gleich zum darauf folgendem else und turn geht...
Die US-hardware funktioniert, mit der gleichen abfrage wird in etwa die entfernung angezeigt, die auch vor den sensoren zur verfügung steht...

#include "asuro.h"
#include "inka.h"
int dist;
int abstand=0;
int i=0;
int j=0;


void umschauen (void)
{
Turn (20, 200);
StatusLED(GREEN);
Msleep(100);
Turn (-40, 200);
StatusLED(YELLOW);
Msleep(100);
Turn (20, 200);
StatusLED(RED);
Msleep(100);
}
void fahren (void)
{
Go (200,150);
Msleep(1000);
Turn (85, 150);
Msleep(1000);
}

void entfernung(void)
{
Init();
SerWrite("\r\n --- ultrasonic test ---",29);
Msleep(1000);

do
{
abstand=Chirp();
SerWrite("\r\n distanz in cm ",16);
Msleep(500);
PrintInt(abstand);

if(abstand > 25) {
StatusLED(GREEN);
Msleep(500);
fahren();
//MotorDir(FWD, FWD);
//MotorSpeed(200, 200);
}
else {
StatusLED(RED);
Msleep(500);
Turn(180,200);
}
}
while(1);
return 0;
}


int main(void)
{
Init();
WaitforStart();

EncoderInit ();
for (j = 0; j < 8; j++)
{
entfernung();
StatusLED(YELLOW);
Msleep(500);
}

//main();
while(1);
return 0;
}
Könnt ihr mir bitte einen tipp geben?

ehenkes
29.06.2007, 18:23
Was soll eigentlich das Init() in entfernung()? Schreib dann auf jeden Fall nochmal EncoderInit() dahinter. Was steht in inka.h?

datobbs
29.06.2007, 22:26
was soll denn die endlosschleife am ende von entfernung()?
was bringt umschaun wenn dus eh nicht benutzt?

ich würd einfachmal en kurzes programm schreiben, dass die ultraschall-entfernung (wenn sie sich ändert) per IR ausgibt
und dann mit der hand enfernungen simulieren

und dann prüfen ob die 25 abstand passen, weil ich sonst nix entdecken kann (wass nix heißen muss :-b )

gruß tobi

ehenkes
30.06.2007, 11:24
@inka: Wenn Du mir die Datei inka.h zeigst, kann ich es gerne testen und den Fehler finden, falls er im Programm verborgen ist. :-k

inka
30.06.2007, 12:23
hi,
erstmal danke für die antworten...
@tobi


was soll denn die endlosschleife am ende von entfernung()?

meinst du while(1) - ist es nicht ein notwendiges teil von "do" weiter oben?



was bringt umschaun wenn dus eh nicht benutzt?

jetzt nichts, eigentlich ist es ja auch später zunächstmal nur ein net aussehneder gag...


und dann prüfen ob die 25 abstand passen

habe ich mit einem eigenständigem programm, dass so aussah wie "entfernung" - incl. ausgaben im terminal, und wie bereits geschrieben, getestet - die entfernung, wenn ich vor die sensoren blatt papier halte (bei der hand funktioniert es nicht so gut, weiss nicht warum), auch angezeigt. Allerdings oft mit ausreissern, die nicht zu der tatsächlichen entfernung passen...
@ehenkes - danke für´s angebot zum testen...
inka.h:

#ifndef INKA_H_
#define INKA_H_

#endif /*INKA_H_*/


/*********************warten auf start****************************/
void WaitforStart(void); // blink until any switch is pressed,
// then wait until switch is released

/********************ultrasonic******************** ***************/
void InitUltrasonics(void);
void RestoreAsuro(void);
int Chirp(void);
inka.c:

#include "asuro.h"
#include "inka.h"
/**************************warten auf start*************************/
void WaitforStart(void) // blink until any switch is pressed,
{ // then wait until switch is released
unsigned int t1, t2;
unsigned int col=OFF;

while (1) // blinking StatusLED until any switch is pressed
{
t1 = PollSwitch();
t2 = PollSwitch();
if (t1==t2)
{
if (t1)
{
break;
}
else
{
col ^= GREEN;
StatusLED(col);
}
}
Msleep(50);
}

StatusLED(OFF); // turn off StatusLED and ...
BackLED(ON,ON); // ... turn on both BackLED's

while (1) // wait until switch is released
{
t1 = PollSwitch();
t2 = PollSwitch();
if (t1==t2)
{
if (!t1)
{
break;
}
}
Msleep(50);
}

BackLED(OFF,OFF); // turn off BackLED's indication start of race
}
/*****************ultrasonic*********************** *********/
/**
* being used insted TIMER2_OVF_vect during ultrasonic polling
*/
ISR(TIMER2_COMP_vect)
{
//TCNT2 += 0x25;
count36kHz++;
if(!count36kHz) timebase++;
}

/**
* initialises the Ultrasonic module
* this function is automaticly called by Chirp
*/
void InitUltrasonics(void)
{
// Change Oscillator-frequency of Timer 2
// to 40kHz, no toggling of IO-pin:
TCCR2 = (1 << WGM21) | (1 << CS20);
OCR2 = 100; // 40kHz @8MHz crystal
TIMSK |= (1 << OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable

ADCSRA = (0 << ADEN); // deactivate ADC
ACSR |= (1 << ACIS1); // Comparator Interrupt on Falling Output Edge

ADMUX = 0x03; // connect ADC3-input with comparator
SFIOR |= (1 << ACME); // connect ADC multiplexer to comparator
DDRD &= ~(1 << 6); // use Port D Pin 6 as input (AIN0)
}

/**
* restores the hardware after using the Ultrasonic module
* this function is called automaticly after a Chirp
*/
void RestoreAsuro(void)
{
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (0 << OCIE2); // OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable

ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64
ACSR |= (0 << ACIS1);

if(autoencode) {
EncoderInit();
}

Sleep(1);
}

/**
* @return distance in cm
*/
int Chirp(void)
{
unsigned int sleeptime = 0, dist = 0;

InitUltrasonics();

// chripen:
count36kHz = 0;

while(count36kHz != 20) {
OCR2 = 100 + 20 / 2 - count36kHz;
}

TCCR2 = (1 << WGM21) | (1 << CS20);
OCR2 = 100;

// analyse echoes:
while(TRUE) {
Sleep(1);
sleeptime++;

if((ACSR & (1 << ACI))) {
dist = (unsigned int) ((long) ((344L * ((sleeptime * 1000L) / 72L) / 10000L) / 2L));
ACSR |= (1 << ACI);
break;
}

ACSR |= (1 << ACI);

if(sleeptime > 3500) {
return -1;
}
}

RestoreAsuro();
return dist;
}


Was soll eigentlich das Init() in entfernung()?
gut, dass mit dem init werde ich rausnehmen und noch einmal testen...

ehenkes
30.06.2007, 12:48
Im Moment ist bei meinem ASURO incl. US die Odometrie nicht kalibriert, aber probiere das mal so:


#include "asuro.h" //incl. US

int abstand=0;
int j=0;

void fahren (void)
{
//EncoderInit();
Go (200,150);
Msleep(1000);
Turn (85,150);
Msleep(1000);
}

void entfernung(void)
{
SerWrite("\r\n --- ultrasonic test ---",29);
Msleep(1000);

do
{
abstand=Chirp();
SerWrite("\r\n distanz in cm ",16);
Msleep(500);
PrintInt(abstand);

if(abstand > 25)
{
StatusLED(GREEN);
Msleep(500);
fahren();
}
else
{
StatusLED(RED);
Msleep(500);
Turn(180,200);
}
}
while(1);
}


int main(void)
{
Init();
EncoderInit ();

for (j = 0; j < 8; j++)
{
entfernung();
StatusLED(YELLOW);
Msleep(500);
}

while(1);
return 0;
}


Damit läuft er mal in den if- und mal in den else-Zweig, und er schickt ständig Werte auf das Hyperterminal. Damit kommst Du weiter.
Die for-Schleife in main() wird übrigens nur einmal ausgeführt, weil er sich ja in entfernung() in der do/while-Schleife fängt. Das macht bezüglich der Ablauflogik keinen Sinn. Das solltest Du ändern.

inka
30.06.2007, 14:40
hi ehenkes,
ich musste vorher noch die ionka.h includen, ohne die dort vorhadenen funktionen für die US-erweiterung kam asuro gleich in den "turn.
bei diesem code:


#include "asuro.h" //incl. US
#include "inka.h"
int abstand=0;
int j=0;

void fahren (void)
{
//EncoderInit();
Go (200,150);
Msleep(1000);
Turn (85,150);
Msleep(1000);
}

void entfernung(void)
{
SerWrite("\r\n --- ultrasonic test ---",29);
Msleep(1000);

do
{
abstand=Chirp();
SerWrite("\r\n distanz in cm ",16);
Msleep(500);
PrintInt(abstand);

if(abstand > 25)
{
StatusLED(GREEN);
Msleep(500);
fahren();
}
else
{
StatusLED(RED);
Msleep(500);
Turn(180,200);
}
}
while(1);
}


int main(void)
{
Init();
EncoderInit ();

for (j = 0; j < 8; j++)
{

entfernung();
StatusLED(YELLOW);
Msleep(500);
}

while(1);
return 0;
}
geht er aber auch sofort in die drehung, an das terminal wird ebenfalls nichts gesendet...

datobbs
30.06.2007, 15:00
ach jetzt versteh ich das while... ](*,) ...hatte vergessen dass das zu do gehört, sorry

ehenkes
30.06.2007, 18:26
So ich habe jetzt die Odometrie in Ordnung gebracht und Dein Programm - wie von mir geändert - nochmals getestet. Bei mir klappt das prinzipiell gut. Allerdings reagiert er noch nicht schnell genug auf Hindernisse. Er rennt dagegen. Das lässt sich aber leicht optimieren.

Dies heißt nun aber, dass bei Dir irgendwo an anderer Stelle im Programmgerüst etwas nicht stimmt. Klappt das bei Dir mit der Status-LED? Geht die auf rot, wenn Du etwas davor hälst, und dann wieder auf grün, wenn alles frei ist?

inka
30.06.2007, 18:32
ich habe auch überlegt und herumgespielt, ich denke es liegt am vorgegebenem abstand >25, das muss ich ändern, weil es bei der messung bei mir aussreiser nach oben wie auch nach unten gibt. Vielleich würde es reichen 2-3mal zu messen, also eine for schleife statt dem do/while und mitteln, ähnlich wie bei den tasterabfragen? Was hälst du davon? Würde das helfen?
Momentan muss ich opfer bringen, komme nicht an "meinen" rechner, meiner tochter hat ferien und spielt simms :-(

ehenkes
30.06.2007, 18:42
Ausreißer sind ein Problem. Ich habe dafür an anderer Stelle mal Folgendes entwickelt, aber das geht sicher noch raffinierter:


#include "asuro.h"
#define MAXDIFF 90

int main(void)
{
int abstand, abstand_alt, diff, zaehler=0;
Init();
abstand = Chirp();

while(TRUE)
{
abstand_alt = abstand;
abstand = Chirp(); ++zaehler;
diff = abstand - abstand_alt;

if( (abstand>15) && (abs(diff)<MAXDIFF) )
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
else if( (abstand>10) && (abstand<=15) && (abs(diff)<MAXDIFF) )
{
StatusLED(YELLOW);
MotorDir(FWD, FWD);
MotorSpeed(150, 100);
Msleep(10);
}
else
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(150, 100);
Msleep(10);
}

if (zaehler > 800)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(200, 250);
Msleep(10);
BackLED(OFF,OFF);
}
if (zaehler > 810)
{
StatusLED(RED);
BackLED(ON,ON);
MotorDir(RWD, RWD);
MotorSpeed(250, 200);
Msleep(10);
BackLED(OFF,OFF);

if(zaehler > 820)
zaehler = 0;
}
}
return 0;
}