PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RP6Control M32: Impulslängen-Messgerät



Dirk
05.03.2010, 19:24
Hallo RP6 Fans,

manchmal hilft ein Impulslängen- und Frequenzmesser:

/*
* ************************************************** **************************
* RP6 ROBOT SYSTEM - RP6 CONTROL M32 TESTS
* ************************************************** **************************
* Example: Impulse length measurement with input capture
* Author(s): Dirk
* ************************************************** **************************
* Description:
*
* With this program the lengths of positive impulses of an unknown TTL signal
* connected to the input capture pin (ICP) of the M32 (PD6, I/O pin 8) can be
* displayed on the LCD.
* If you uncomment the definition FREQUENCY, the frequency of the unknown TTL
* signal will be displayed instead of the impulse length.
*
* ################################################## ##########################
* The Robot does NOT move in this example! You can simply put it on a table
* next to your PC and you should connect it to the PC via the USB Interface!
* ################################################## ##########################
* ************************************************** **************************
*/

/************************************************** ***************************/
// Includes:

#include "RP6ControlLib.h" // The RP6 Control Library.
// Always needs to be included!

/************************************************** ***************************/
// Defines:

//#define FREQUENCY // Measure the frequency
// (instead of the impulse length)

/************************************************** ***************************/
// Variables:

typedef union {
uint32_t i32;
struct {
uint8_t i8l; // Low byte
uint8_t i8m; // Middle byte
uint16_t i16h; // High uint
};
} icrcounter_t;

volatile uint16_t ovfcnt = 0; // Number of overflows during
// the measurement
volatile uint32_t timediff;
uint32_t time;
double result;

#define FALLING_EDGE 0 // (or next rising edge)
#define RISING_EDGE 1
volatile uint8_t edgeflag;

char buffer[12]; // Buffer for ASCII conversion

/************************************************** ***************************/
// Functions:

/**
* TIMER1 Overflow ISR
*
* In this ISR the ICR1 overflows are counted.
*
*/
ISR (TIMER1_OVF_vect)
{
++ovfcnt; // Count the overflows
}

/**
* TIMER1 Capture ISR
*
* In this ISR the cycles from a rising edge to the falling (or the next
* rising) edge are calculated.
*
*/
ISR (TIMER1_CAPT_vect)
{static icrcounter_t icrcnt_start;
icrcounter_t icrcnt_end;
if (edgeflag == RISING_EDGE) { // Rising edge!
icrcnt_start.i8l = ICR1L; // Low byte first
icrcnt_start.i8m = ICR1H; // High byte is buffered
ovfcnt = 0; // Reset overflow counter
#ifndef FREQUENCY
TCCR1B &= ~(1<<ICES1); // Next trigger: Falling edge
#endif
edgeflag = FALLING_EDGE;
}
else { // Falling (or next rising) edge!
icrcnt_start.i16h = 0; // Reset upper 16 bits (start value)
icrcnt_end.i8l = ICR1L; // Low byte first
icrcnt_end.i8m = ICR1H; // High byte is buffered
// If low ICR1H and waiting overflow interrupt:
if ((icrcnt_end.i8m < 128) && (TIFR & (1<<TOV1))) {
// Do the job of the waiting timer overflow interrupt:
++ovfcnt;
TIFR = (1<<TOV1); // Clear Timer1 overflow interrupt
}
icrcnt_end.i16h = ovfcnt; // Upper 16 bits (overflow counter)
timediff = icrcnt_end.i32 - icrcnt_start.i32;
#ifndef FREQUENCY
TCCR1B |= (1<<ICES1); // Next trigger: Rising edge
#endif
edgeflag = RISING_EDGE;
}
}

/************************************************** ***************************/
// Main function - The program starts here:

int main(void)
{
initRP6Control(); // Always call this first! The Processor will not
// work correctly otherwise.

initLCD(); // Initialize the LC-Display (LCD)
// Always call this before using the LCD!

// Write some text messages to the LCD:
showScreenLCD("################", "################");
mSleep(1500);
showScreenLCD("<<RP6 Control>>", "<<LC - DISPLAY>>");
mSleep(2500);
showScreenLCD("Imp. Measurement", "Version 1.00 ICP");
mSleep(2500);
clearLCD(); // Clear the whole LCD Screen

// Clear the four Status LEDs:
setLEDs(0b0000);

// Initialize the M32 ICP pin (PD6) as input:
DDRD &= ~IO_PD6;
PORTD |= IO_PD6; // Pullup on

// Initialize the M32 Timer1 input capture function:
edgeflag = RISING_EDGE;
TCCR1B = (1<<ICES1) | (1<<CS10) // Trigger: Rising edge, no prescaling
| (1<<ICNC1); // and noise canceler
TIMSK = (1<<TICIE1) | (1<<TOIE1); // Activate capture & overflow ISR
TIFR = (1<<TOV1) | (1<<ICF1); // Clear active interrupts

while(true)
{
cli();
time = timediff;
sei();
if (time > 0) {
ultoa(time, buffer, DEC); // Convert to ASCII
setCursorPosLCD(0, 0);
writeStringLCD("CNT "); // Counter value ( / F_CPU [s])
writeStringLCD(buffer);
writeStringLCD(" ");

setCursorPosLCD(1, 0);
#ifndef FREQUENCY
result = (double) time / F_CPU;
writeStringLCD("IMP "); // Impulse length [s]
dtostrf(result, 11, 7, buffer); // Convert to ASCII
#else
result = (double) F_CPU / time;
writeStringLCD("FRQ "); // Frequency [Hz]
dtostrf(result, 11, 3, buffer); // Convert to ASCII
#endif
writeStringLCD(buffer);
TIFR = (1<<TOV1) | (1<<ICF1);
}
}
return 0;
}

/************************************************** ****************************
* Additional info
* ************************************************** **************************
* Changelog:
* - v. 1.0 (initial release) 27.02.2010 by Dirk
*
* ************************************************** **************************
*/

/************************************************** ***************************/


Dieses Programm macht die M32 zu einem solchen "Messgerät" mit der Input Capture Funktion.

Viel Spaß damit

Gruß Dirk

radbruch
05.03.2010, 20:30
Gibt es eigentlich einen besonderen Grund für die englischen Kommentare?

Dirk
05.03.2010, 21:12
Hallo radbruch,

Möglichkeiten:
1. Ich will mein Englisch üben
2. Ich mache es genau so wie bei den RP6 Beispielen
3. Ich bin Engländer
4. Ich liebe die Queen
5. Ich denke, wer programmiert, sollte Englisch können
6. Mein Goldfisch heißt Timothy
7. Ich will nur angeben
8. Ich bin ein bißchen crazy (Entschuldigung: verrückt)
9. Mein Französisch ist zu schlecht

Du kriegst 100 Punkte, wenn du das Richtige herausfindest!

Lieben Gruß O:)
Dirk

RobbyMartin
05.03.2010, 21:45
dein französisch ist zu sclecht ;-)

Dirk
05.03.2010, 21:56
Oui, mon cher. \:D/

radbruch
05.03.2010, 23:01
Hallo Dirk

Danke für deine ausführliche Antwort. Den wahren Grund in deiner Auswahl zu finden fällt mir echt schwer, jeder für sich würde für mich schon deine englischen Kommentare begründen. Was ich nun aber nicht nachvollziehen kann:

Warum schreibst du denn deine Beiträge nicht komplett in englisch?

Mit ebenfalls liebem Gruß

mic

Dirk
06.03.2010, 08:40
Hallo mic,

sorry! Ich hätte vielleicht nicht so flapsig mit deiner Frage umgehen sollen.

Die wahre Antwort ist:
Meine Programme für den RP6 schreibe ich im Stil von SlyD, weil er dem RP6 schon ein eigenes Gepräge gibt. Dazu gehört nicht nur die Form, sondern auch die englischen Kommentare (mit Ausnahme der C-Control M128). Mir gefällt es, dass man auf einen Blick erkennen kann: Das Prog ist für den RP6.
Natürlich muss man das nicht so machen, obwohl ich denke, dass die Programmteile, die man hier häufig sieht, ein bißchen Form gut gebrauchen könnten.
Dann bin ich zu faul, meine Progs vor der Veröffentlichung abzuändern.

Also: Am besten trifft Nr. 2 zu, aber auch an Nr. 5 ist etwas dran.
Nr. 7 trifft überhaupt nicht zu, und ich habe auch keinen Goldfisch, aber meine Frau hat mit der Queen zusammen Geburtstag.

In einem deutschen Forum schreibe ich natürlich auch Deutsch.

Frage an den Moderator radbruch: Würdest du denken, dass wir Programme hier eher mit deutschen Kommentaren reinstellen sollten? Ich werde das dann gern machen.

Lieber Gruß (das meine ich so!!)
Dirk

radbruch
07.03.2010, 18:46
Hallo Dirk

Erstmal danke für deinen zweiten Anlauf. Diese Argumente klingen nun gar nicht mehr flapsig.

Der RP6 wird in Asien produziert und weltweit verkauft. Deshalb blieb SlyD bei der Entwicklung der Library wohl auch keine andere Wahl als englisch zu kommentieren. Da du unter all den RP6-Benutzern, die sich hier im Forum tummeln, der einzige bist, dessen Programme in den Bereich von SlyDs Meisterleistung kommen, kann ich gut nachvollziehen, dass du dich seiner Gestaltung der Quellcodes anpassen willst.

Umso überraschter bin ich nun vom Quellcode in diesem Thread:
https://www.roboternetz.de/phpBB2/viewtopic.php?t=53051

Auf den ersten Blick eindeutig als typisches RP6-/M32-Programm nach Vorbild der Library erkennbar, fällt der deutsche Kommentar erst auf den zweiten Blick auf. Wirklich super. Ich denke, ich bin nicht der Einzige hier, dem das sehr gefällt. Danke.

Gruß

mic

Dirk
07.03.2010, 19:18
Ok, danke!

Werde bei deutschen Kommentaren bleiben!

Gruß Dirk

inka
06.07.2014, 18:56
Hallo Dirk,

diese schaltung stammt aus dem IR-bake thread:

28560
bei der schaltung versuche ich nun eine definierte blinkfrequenz einzustellen. Eigentlich dachte ich, es müsste auch auf dem OSZI zu sehen sein in welcher frequenz der blinker den zustand ändert, geht aber irgendwie nicht, ich bekomme nur eine durchgezogene linie angezeigt, die in einem bestimmten rhythmus von einem level zum anderen springt. Ich kann also diese beiden level ablesen, wollte aber eigentlich was anderes...

Da habe ich mich an dieses programm erinnert...

habe die zeile "#define FREQUENCY" aktiviert, den code compiliert (keine fehlermeldungen) und in die m32 geladen. Die meldungen beim start kommen wie es im code steht, dann bleibt aber das display leer, egal ob meine schaltung angeschlossen ist oder nicht.


Anschluss der blinkerschaltung nach dem hier:


der I/O Pin 8 vom IO-Mxxx landet am Jumperblock J_IO an dem Pin, der mit "8" beschriftet ist.
Das ist der 2. Pin von links,- oben drüber steht "Rx" und eine beliebige masse (habe den GND pin auf der multi I/O auf der Gyro pinnleiste, neben dem XBUS wannenstecker genommen)


was ist da falsch? Ich weiss nicht, aber sollte das display nicht noch etwas anzeigen bevor gemessen wird?

danke für Deine zeit...

Dirk
06.07.2014, 19:16
Hi inka,

nein, wenn kein Input-Signal anliegt, zeigt das Display erstmal nix.

Der Anschluss an die MultiIO ist auch so ok, d.h. PD6 der M32 liegt am J_IO da, wie du beschrieben hast.
Von den beiden Pins an Position 2 von links hast du doch den "unteren" genommen (drunter steht "8") und nicht den "oberen", über dem "Rx" steht?

Beim Oszi müßtest du die horizontale Ablenkung ganz runterdrehen (z.B. 0,5s /DIV),- allerdings kann so ein niederfrequentes Signal nicht immer gut eingefangen werden. Gehen müßte das aber mit der Synchronisation auf z.B. die steigende Flanke.

inka
07.07.2014, 07:45
Hi Dirk,

leider habe ich den falschen pin erwischet - inzwischen zeigt das display aber die "nach gefühl" eingestellten 2 Hz mit 2.014 an...


frage: lassen sich mit diesem programm (nach anpassung) die werte auch an anderen pins, z.b. den PB2 anzeigen? Dann würde ich ja nicht nur erkennen ob eine bake gefunden wurde, sondern auch welche...

EDIT: vergiss die frage - PB2 ist ja nur ON/OFF info :-(

RolfD
07.07.2014, 19:46
Also ich bin mir auch nie einig ob ich english oder deutsch kommentieren soll.
Das liegt aber daran, das ich für mich schon immer und seid Z80 Assembler Zeiten konsequent englisch kommentiert habe - schon deshalb weil es bis vor 10 Jahren auch kaum deutsche Literatur dazu gab und englisch nun mal die IT Sprache schlechthin ist.. selbst die Chinesen proggen in englisch!
Irgendwann in den letzten Jahren kamen "Anfragen" von wegen "blä.. kann ja keiner lesen ...mach deutsch" ... und ich hab angefangen das eine oder andere aus Gefälligkeit umzuschreiben oder direkt in deutsch zu kommentieren. Allerdings bin ich der Meinung, das - egal ob deutsch oder englisch - man sich vor allem damit auseinander setzen muss was gecodet wurde und die paar Brocken Kommentar machen es nicht aus. Für Leute die kein Schulenglisch hatten ist das dann schwieriger - seh ich ein...
Aber es geht primär um den Code und neben tausenden von Webseiten wo man sich heute sein Programmcode zusammen klauen kann gibts z.B. inzwischen auch gute Übersetzerwebseiten.
Gruß

Dirk
07.07.2014, 20:28
Hi inka,

frage: lassen sich mit diesem programm (nach anpassung) die werte auch an anderen pins, z.b. den PB2 anzeigen? Dann würde ich ja nicht nur erkennen ob eine bake gefunden wurde, sondern auch welche...
EDIT: vergiss die frage - PB2 ist ja nur ON/OFF info
Man kann das Frequenz-Messprogramm auch mit einem Interrupt-fähigen Pin machen. Das wäre bei der M32 dann PB2, PD2, PD3.
Dazu müßte man das Prog etwas umschreiben ...

inka
23.10.2014, 17:07
hi Dirk,

die verbindung von J_IO Pin8 nach ON_L (am rechten Jumperblock) soll ja die auswertung der bumper der multi-IO platine ermöglichen.

29252

der gleiche pin wird in dem impulslängen messgerät verwendet. So lange man durch umstecken entweder das eine oder das andere macht ist es sicher unproblematisch. Wird es zum problem, wenn man den pin 8 z.b. auf eine EXP rausführt und dauernd daran die frequenz misst? Kann man dann "nur" nicht gleichzeitig den bumper auswerten, oder passiert etwas schlimmeres?

der grund meiner frage:
um Probleme zu vermeiden wäre es evtl. sinnvoll einen anderen port/pin zu nehmen. Ich habe es so versucht:


// Initialize the M32 ICP pin (PD6) as input:
/*
DDRD &= ~IO_PD6;
PORTD |= IO_PD6; // Pullup on
*/
// Initialize the M32 MEM_CS2 pin (PB1) as input:

DDRB &= ~ MEM_CS2;
PORTB |= MEM_CS2; //Pullup on


Also der wald voller ports und pins lichtet sich ein wenig, hell ist es aber noch lange nicht...



Dass ich nach wie vor am M32 ICP pin (PD6) die frequenz messen konnte erkläre ich mir damit, dass ich nicht alles im programm geändert habe(?) und der PD6 immer noch als input pin für die messung initialisiert war (so lange bis die festlegung von input wieder auf output geändert wird), oder?
Dass am MEM_CS2 (PB1) also meinem USRBUS pin 3 (ist herausgeführt vom pin1/IC5) aber garnichts ankam - da habe ich keine erklärung für...

Dirk
23.10.2014, 21:08
Hi inka,

Wird es zum problem, wenn man den pin 8 z.b. auf eine EXP rausführt und dauernd daran die frequenz misst? Kann man dann "nur" nicht gleichzeitig den bumper auswerten, oder passiert etwas schlimmeres?
Nein, das müßte gehen. Du must dann halt auf den Bumper links verzichten, also KEINE Verbindung zwischen J_IO Pin 8 und ON_L auf der MultiIO herstellen.


Dass am MEM_CS2 (PB1) also meinem USRBUS pin 3 (ist herausgeführt vom pin1/IC5) aber garnichts ankam - da habe ich keine erklärung für...
Das "Impulslängenmessgerät" funktioniert so wie es ist nur mit dem ICP Pin.