RP6Control M32: Impulslängen-Messgerät
Hallo RP6 Fans,
manchmal hilft ein Impulslängen- und Frequenzmesser:
Code:
/*
* ****************************************************************************
* 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
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Dirk,
diese schaltung stammt aus dem IR-bake thread:
Anhang 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:
Zitat:
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...