Hallo liebe Community,
Momentan bin ich dabei mein Inkrementalmesssystem (Anbaumessschieber von
Wabeco) mit einem XMega zu verheiraten, damit ich diesen an meiner Fräse
anbauen kann...
In diesem Beitrag wollte ich die Fachmeinung der Kenner wissen (bin
selbst kein Elektrotechniker). Zur Allererst habe ich mit einem
Oszilloscop die Ausgänge des Messschiebers überprüft. Ich messe auf der
Taktleitung ein Paket, welches etwa 12,5 ms lang ist, danach kommt 170
ms nichts dann kommt das gleiche Paket wieder. Ein Bild des Oszis ist
angehängt Oszi1.PNG.
----------------Oszi1.PNG-----------------
Anscheinend arbeitet der Messschieber intern in 1/100 mm, denn wenn ich
die Messleiste um 0,01 mm verschiebe, so verschwindet auf der
Datenleitung (Gelb) das erste "Bit" (oder wie heißt es in den
Fachkreisen?). Die negativen Werte sieht man anhand des letzten Paket.
Denn dort wird der erste Bit dann "Low" (die restlichen überflüssig). Zu
sehen in dem Bild Oszi2.PNG
----------------Oszi2.PNG-----------------
Um die Daten auszulesen brauche ich also nur 2 Pins. Bei diesen wird
dann der Zustand verglichen und bei Übereinstimmung ist der Bit 0 bei
Nichtübereinstimmung ergibt es eine 1. Sollte man eine Funktion zum
vergleichen schreiben, welche dann binären Wert liefert. Auf diese
Funktion wird von einer anderen Zugegriffen, welche den Wert dann
zusammensetzt zu einem Integer. Und dieser Integer ist mein Messwert.
----> Zu den Fragen <----
1.) Ist der Gedankengang ok?
2.) Gibt es eine elegantere Methode den Pegel auszulesen?
3.) Meinen XMega will ich mit 3,3 V Betreiben (denn sonst mein LCD-Modul
Probleme macht), der Messschieber arbeitet bei 1,5 Volts. Ich will einen
4fachen Operationsverstärker nehmen und diesen in einer
nichtinvertierender Verstärkerschaltung betreiben um die Spannung zu
verdoppeln (zwei TS272). Ist es eine optimale Lösung?
4.) Idee ist, dass der Mikrokontroller eine lineare Regression ausführt
und intern nach einer Kalibrierung mittels Prüf-Messwerte die
Berechneten(theoretisch richtigen) Werte für die Messung anzeigt.
Schafft ein Mikrokontroller eine Lineare Regression zu berechnen? Und
das Alles soll für 4 Messschieber Funktionieren!?!?
Ich bitte sie um konstruktive Beiträge
Viele Grüße Alex
Du kannst z.B. die vorhandene SPI-SChnittstelle von Deinem XMega
benutzen, die ist speziell für sowas gemacht. Dann liest Du 3 Byte ein
und baust daraus ein Long integer, damit kannst Du alle Werte abbilden,
die das Ding liefern kann.
Zur Anpassung der Pegel gibt es Artikel in der Artikelsammlung.
"lineare Regression" ist ein bischen hochgreifend formuliert. Wieviele
Kalibrierungspunkte hast Du denn? Wenn es nur Anfang und Ende mit den
jeweiligen Messwerten sind, dann ist der Rest ein Dreisatz. Dass schafft
der uC.. :-)
Für 4 Signale kannst Du entweder mehrere SPI -Schnittstellen als
Software emulieren, oder Du baust Dir aus Logikbausteinen einen
Umschalter, mit dem Du immer nur ein Leitungspaar zur SPI durchlässt.
Danke für deine Antwort!
SPI zu benutzen ist eine sehr gute Idee.
Habe mir nun eine Bidirektionalen 8-Bit Pegelwandler besorgt, durch den
ich meine 3,3V für Mikrocontroller bekomme.
Habe bischen im Datenblatt des X-Mega's bezüglich der SPI-Interfaces
gelesen. Da steht, dass man ja nur 4 Register braucht. Das CTRL,
INTCTRL, STATUS und DATA.
In das CTRL-Register schreibe ich eine 0x6C da es ja gerade meinen
einstellungen entspricht: 01101100 (Clock-Double ist --> 0, SPI-wird
eingeschaltet --> 1 ; LSB first --> 1 ; Slave-Modus --> 0 ; SPI-Mode 3
--> 1 --> 1 und Prescaler --> 0 --> 0 ) das in Hexadezimal: 0x6C, also
CTRL = 0x6C. Das INTCTRL setze ich 0.
Wenn ich nun auf dem Steckboard das alles verdrahte und LCD anschließe,
so bekomme ich wirre werte...
Mit dem STATUS Register habe ich schwierigkeiten...
Ich Kriege je von dem Messschieber 24 Bits, das sind 3 mal 8-Byte
Pakete. Ich muss also irgendwie den DATA-Register mit hilfe des STATUS
Registers 3 mal pro Datenübertragung auslesen und dabei einen uint32_t
erzeugen ?.?.?.? weiß momentan nicht weiter. Kann mir eventuell jemand
Literaturhinweis geben?
Hier mein Code:
1
/*
2
* ATXmega16A4_AU.c
3
*
4
* Created: 01.10.2012 21:06:30
5
* Author: Alex
6
*/
7
8
#define F_CPU 32000000UL
9
#define FALSE 0;
10
#define TRUE 1;
11
12
13
#include<avr/io.h>
14
#include<util/delay.h>
15
#include"lcd-routines.h"
16
17
// Das ist eine Funktion zur Einstellung des internen 32 MHz Schwingers
18
19
voidClock_init(void)
20
{
21
OSC.CTRL|=OSC_RC32MEN_bm;
22
while(!(OSC.STATUS&OSC_RC32MRDY_bm));
23
CCP=CCP_IOREG_gc;
24
CLK.CTRL=0x01;
25
}
26
27
intmain(void)
28
{
29
Clock_init();
30
31
lcd_init();
32
33
SPIC.CTRL=0x6C;//Setzen des CTRL-Registers
34
SPIC.INTCTRL=0;
35
uint32_ti=0;
36
charpuffer[20];
37
lcd_clear();
38
lcd_string("Anzeige: ");
39
40
while(1)
41
{
42
i=SPIC.DATA;
43
ultoa(i,puffer,10);
44
lcd_setcursor(9,1);
45
lcd_string(puffer);
46
_delay_ms(10);
47
}
48
49
return0;
50
}
---------------- Zur Linearen Regression ------------------
Zur Kalibrierung habe ich 7 Wertepaare alle symmetrisch entlang 175 mm
verteilt mit Genauigkeit von unter pm 0,01 mm. Die Abschätzung des
Quadrat der Standartabweichung lautet:
Nun minimiert man die Parameter bezüglich a und b:
ergibt sich das Gleichungsystem:
Als Lösung des Gleichungsystems erhält man:
und für den Linearen Koeffizienten b:
Hier ist D die Determinante und beträgt:
Wie man nun sieht müssen die 3-fachen Produkte berechnet werden über die
Summen der Wertepaare. hmmm Schafft der Mikrokontroller das?
Alexej W. schrieb:> Zur Kalibrierung habe ich 7 Wertepaare alle symmetrisch entlang 175 mm> verteilt mit Genauigkeit von unter pm 0,01 mm.
Und wie liegen deine Werte in Relation zu einer Geraden. Eine
Kalibrierung ist nur sinnvoll, wenn der Zusammenhang reproduzierbar ist
und nicht bei der nächsten Kalibiermessung ganz anders aussieht. Ggf.
benötigt man z.B. zusätzlich einen Temperaturfühler für Korrekturen.
Japp das ist dann für Später als Erweiterung gedacht.
Aktuell lese ich die Werte manuell ab und berechne diese mit einem
kleinen Progrämmchen, die Berechnung dauert zwar kurz auf meinem
Werkstatt-Rechner, geht aber. Die Werte weisen eine sehr gute Linearität
auf, so dass es wie oben erwähnt nur von der Umgebungstemperatur und dem
linearen Wärmeausdehnungskoeffizienten abhängt.
Später wollte ich einen PT100 oder sowas an Mikrokontrollen anschließen,
welcher dann vergleicht ob die Temperatur im Raum sich geändert hat oder
nicht und dann etscheidet ob eine neue Kalibrierung vorgenommen werden
muss....
Hallo,
Bitte um Hilfe bezüglich Code...
Habe nun bischen recheschiert und herausgefunden was ich brauche, es
klappt jedoch nicht!
Ich muss also 3 Bytes nacheinander auslesen und diese dann in ein
uint32_t zusammenfügen. Danach muss ich ja den Wert einmal spiegeln und
dann ist er theoretisch fertig.
Hier mein Code:
1
/*
2
* ATXmega16A4_AU.c
3
*
4
* Created: 01.10.2012 21:06:30
5
* Author: Alex
6
*/
7
8
#define F_CPU 32000000UL
9
#define FALSE 0;
10
#define TRUE 1;
11
12
13
#include<avr/io.h>
14
#include<util/delay.h>
15
#include"lcd-routines.h"
16
17
18
//Funktion zur Einstellung des internen 32 MHz Schwingers
//3 Bytes aus dem SPI Auslesen und in ein uint32_t reinschreiben
35
uint32_tspi_bytes_empfangen(void)
36
{
37
uint32_tdata=0;
38
data=SPIC.DATA;//Daten-Register auslesen
39
data<<=8;//data um 8 Bits nach links schieben
40
data|=SPIC.DATA;//hänge ein Byte aus dem Daten-Register rechts an data an
41
data<<=8;//data um 8 Bits nach links schieben
42
data|=SPIC.DATA;//hänge ein Byte aus dem Daten-Register rechts an data an
43
returndata;//Ausgabe des data-Wertes
44
}
45
46
//Spiegelung eines uint32_t, hier wird bitweise der neue uint32 zusammengesetzt
47
uint32_tspiegelnuint32(uint32_tinput)
48
{
49
uint32_toutput=0;
50
for(uint8_ti=1;i<=32;i++)
51
{
52
output|=input&i<<(32-i);
53
}
54
returnoutput;
55
}
56
57
intmain(void)
58
{
59
Clock_init();
60
Spi_init();
61
lcd_init();
62
63
uint32_ti;
64
charpuffer[20];//Anlegen eines Strings von Länge 20 Zeichen
65
lcd_clear();
66
lcd_string("Anzeige X: ");
67
68
while(1)
69
{
70
i=0;
71
i=spiegelnuint32(spi_bytes_empfangen());//Hier wird nun der empfangene uint32_t gespiegelt und dem i zugewiesen
72
ultoa(i,puffer,10);//Funktion zur Umwandlung eines Unsignet-Longs zu String puffer in der Dezimalen Darstellung
73
lcd_setcursor(11,1);
74
lcd_string(puffer);
75
}
76
77
return0;
78
}
Wenn ich das Programm compiliere, so sehe ich auf dem LCD als Position
0, sobalt ich den Messchieber um 0,01mm bewege ändert sich der Wert
sofort auf 05792. Bei Wert 0,02 mm ist LCD bei 031586. Wenn ich nun den
Messschieber resete, dann ist die LCD-Anzeige bei dem alten Wert, obwohl
nach einem Reset die Data-Leitung eine 0 liefert...
Sehe momentan keinen Fehler im Code.
Bitte um Hilfe
Grüße Alex