Mätapplikation med Arduino och Java

Berätta om dina pågående projekt.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Så här ser en typisk NTC-Temperaturkurva ut för den som inte sett en sån innan.

Det skulle gå att få till mätvärden tätare än 1 grad men vitsen är nog inte så stor, en sån här kurva räcker långt
i många tillämpningar av NTC-motstånd.

Med det värmeelement jag använder nu tar tiden från 25 grader till 100 grader alltså ca: 13 minuter.
Använder en 30W lödpenna.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Den lite vågiga kurvan?
Kan den bero på att kylflänsen inte är termiskt isolerad?
Om jag till exempel svepte förbi på vägen till kaffebryggaren så blev det luftcirkulation runt aluminiumbiten.
Fast då måste det väl bero på olika termisk tidskonstant hos NTC och sensorn.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Tänkte utföra en jämförelse med 2st NTC jag inhandlat som ska ha liknande data
och se hur väl de matchar. Här är kurvan för NTC A.

Måste vänta på att elementet kallnar
och det tar längre tid än man tror från 150 ned till 23.

Det kan man faktist säga är en
nackdel med instrumentet i nuläget.

Kanske man skulle ha några aluminiumbitar att växla
mellan för att instrumentet ska bli smidigare att använda då flera NTC ska mätas upp.

Tror det blir billigare/enklare än att ha fler mätkretasar och mäta samtidigt.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Lite i framtiden funderar jag och fantiserar om arduinobaserade transistorkurvor, diodkurvor och diverse fysikaliska kurvor.
Jag har ju helt klart grundkoden för dessa fysikaliska förlopp i min hand.
Många problem på vägen så klart.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Caddade ett shield som fanns med i ett bibliotek.

Nu var yttermåtten inte riktigt som jag önskade men
stiftlisterna satt rätt så jag caddade in nya och
placerade ovanpå och tog sedan bort symbolen för shield.

Sedan i stället för att ha små kort med olika bryggor att växla med
så har jag ett kort med flera bryggor som jag kan koppla in med en
flatkabel.

Sedan ska bryggan kalibreras med 3 olika motstånd och de kommer bli
olika beroende på värdet på NTC-resistorn. Då kan jag ha en vridswitch
med 12 lägen och välja bland olika lämpliga motstånd.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Bryggor och kalibreringsmotstånd.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Här är två NTC inhandlade med samma värde.
Mätte upp till 150 grader från rumstemperatur.
De skiljer mest i resistans vid lägre temperatur.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Behöver ett relä till lödkolven/värmeelementet så jag kan slå till och ifrån det.
Hittade en applikation med 555 som drivare, ofta klarar de 150mA som passar bra till
den typen av relä jag tänkt använda. (SAMS, The 555 Timer Application Sourcebook av Howard M. Berlin).
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Så då är korten etsade och borrade.
Måste köpa hem lite komponenter.
Electrokit hade sånna där lister så det går stacka skölden men det verkade vara slut i lager.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Funderar på om mina kunskaper i Java skulle räcka för en anställning? Om inte vad saknar jag för kompetens?
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

64000 views!!

Kan det vara möjligt?

Jag måste avsluta projektet och få till en låda.

Varför avslutar jag inte utan börjar på ett nytt projekt?

Är jag ensam på den fronten ?

Nej tror inte det ?
Användarvisningsbild
carpelux
Inlägg: 1865
Blev medlem: 13 oktober 2007, 12:33:33
Ort: Varnhem

Re: Mätapplikation med Arduino och Java

Inlägg av carpelux »

Nej du är nog inte ensam om det. Jag vet minst en till😀

Bra jobbat!
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Skönt att inte känna sig ensam. :)

Men antalet views på tråden rimmar dåligt med antalet views på bilderna?
Fast har 250 sett bilden och sedan kommer tillbaka en andra gång utan att behöva kika på bilden på nytt så blir det väl så?
Användarvisningsbild
4kTRB
Inlägg: 18279
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

På Eclipse Marketspace finns sloeber att hämta hem som plug-in.
Det jag använde innan för detta projekt har de tagit bort så sloeber är nu enda alternativet.

Har kodat lite ändringar i C-koden och så fungerar det nu inte att
deklarera på följande vis

typedef char* CharPointer;
CharPointer Rb = "RA";
CharPointer Rb = "RB";
CharPointer Rc = "RC";

eller jo, ibland tycker kompilatorn att det är ok.

Snyggade till några kommentarer och efter det gick det inte kompilera utan att få fel.

Så jag kodade så här och det fungerar varje gång

char Ra[] = "RA";
char Rb[] = "RB";
char Rc[] = "RC";


void rRefAdjust(char[]);

Anrop:
rRefAdjust(Ra);


Ska C-kompilatorer ändra sig på det viset?

Hela koden...

Kod: Markera allt

#include "Arduino.h"
#include <Adafruit_MAX31865.h>

// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 max = Adafruit_MAX31865(10, 11, 12, 13);
// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
// #define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
// #define RNOMINAL  100.0

static const float RREF = 430.0;
static const float RNOMINAL = 100.0;

// ****************************************************
//  Variabler och konstanter för kalibrering av brygga
// ****************************************************
int analogPinA = A0;                  						// bryggans anslutning A
int analogPinB = A1;                  						// bryggans anslutning B
int celcius;
int inByte = 0;
const int NUMBER_OF_SAMPLES = 100;            				// medelvärdesbilda AD-omvandla många gånger
const unsigned long BAUDRATE = 19200;

// samma funktion används för att kalibrera med
// RA,RB och RC, bara olika id-för java-datorn
char Ra[]  = "RA";
char Rb[]  = "RB";
char Rc[]  = "RC";

// ****************************************************
// 0 är startsignal för datainsamling i Arduinos meny
// 1 är startsignal för nollkalibrering av brygga med RA i Arduinos meny
// 2 är startsignal för kalibrering med RB i Arduinos meny
// 3 är startsignal för kalibrering med RC i Arduinos meny
// 4 är Exit i Arduinos meny
// 5 är startsignal för kontinuerlig spänningsmätning av bryggans obalans
// WHILE_LOOP_BREAK abryter while-loop i respektive mätloop

const byte COLLECT_DATA = 0;
const byte CALIBRATE_RA = 1;
const byte CALIBRATE_RB = 2;
const byte CALIBRATE_RC = 3;
const byte EXIT = 4;
const byte MEASURE = 5;
const byte WHILE_LOOP_BREAK = 127;


// Funktionsdeklarationer
// ****************************************************
void measure();
void rRefAdjust(char[]);
// void bridgeZeroAdjust();
void averageData(double&, double&, double&);
void adjustAlert(double);
void ntcMeasurement();
int avrunda(double);
void setCelcius(int);
int getCelcius();

void setup() {
	Serial.begin(BAUDRATE);
	setCelcius(0);
	pinMode(LED_BUILTIN, OUTPUT);
	digitalWrite(LED_BUILTIN, LOW);     					// används för att testa programmet
	while (!Serial) {
		; 										// wait for serial port to connect. Needed for native USB
	}
	max.begin(MAX31865_2WIRE);  						// set to 2WIRE or 4WIRE as necessary
}

// En loop med meny. Data skickas från JAVA-datorn och olika saker utförs.
// Inga av de funktioner som väljs att exekveras körs som trådar på Arduino
// så för att menysystems-loopen ska kunna hantera nästa kommando måste
// den funktion som pågår först avslutas, innan dess case-break; tillåter
// fler menyval. I GUI så kan inte fler menyval utföras förrens det pågående
// avslutats, undantag gäller EXIT för programavslut.
void loop()
{
	if (Serial.available() > 0)
	{
		inByte = Serial.read();
		switch (inByte){
		case COLLECT_DATA:                 			 // en NTC-mätning är begärd
			digitalWrite(LED_BUILTIN, HIGH);
			ntcMeasurement();         			 	// funktion med while-loop, tar en stund
			break;               				 	// först nu kan nya menyval utvärderas
		case CALIBRATE_RA:
			digitalWrite(LED_BUILTIN, HIGH);
			//bridgeZeroAdjust();        			 // en loop som hela tiden indikerar om bryggan är nolltrimmad eller ej
			rRefAdjust(Ra);
			break;               		 		 	// fortsätt i meny-loop när bridgeZeroAdjust() har avslutats
		case CALIBRATE_RB:
			digitalWrite(LED_BUILTIN, HIGH);
			rRefAdjust(Rb);						 // en loop som hela tiden indikerar spänningen från bryggan
			break;							// med kalibreringsmotståndet Ra anslutet
		case CALIBRATE_RC:
			digitalWrite(LED_BUILTIN, HIGH);
			rRefAdjust(Rc);
			break;
		case MEASURE:
			digitalWrite(LED_BUILTIN, HIGH);
			measure();
			break;
		case EXIT:								 	 // Avsluta. Kvittera till Java-datorn och Stäng serieporten
			digitalWrite(LED_BUILTIN, HIGH);
			Serial.write("EXIT FROM ARDUINO");			// Java-datorn skannar data från Arduino mha
			Serial.write("\n");					  	// java.util.Scanner.Scanner(InputStream source)
			Serial.end();			  			  	// nedkoppling av seriekommunikation/com-port
			break;
		default:
			digitalWrite(LED_BUILTIN, LOW);
		}
	}
	delay(100);
	digitalWrite(LED_BUILTIN, HIGH);              				// visuell indikering att Arduino är aktiv utanför menyloopen
	delay(100);
	digitalWrite(LED_BUILTIN, LOW);
}
/*
 * Tar hand om  A/D-omvandlingar från två ingångar.
 * De insamlade värdena från respektive ingång är medelvärdesbildade
 * och de två ingångarnas differens-spänning skickas till Java-datorn.
 * Upplösningen är 5/1023 = 4.888 mV per bit. Differensspänningen
 * levereras som ett avrundat heltal motsvarandes antal bitar (0 till 1023).
 * Funktionen används för att ta fram ekvationen för en noll-
 * trimmad brygga mha två fasta och kända resistanser, RA, RB och RC.
 * Loopen avbryts manuellt från GUI med tryck på en knapp.
 */
void rRefAdjust(char c[]){
	bool breakFlag = true;
	double averageVoltA;
	double averageVoltB;
	double vDiff;
	Serial.write(c);										// Java-datorn skannar data från Arduino mha
	Serial.write("\n");									// java.util.Scanner.Scanner(InputStream source)
	while(breakFlag){									// Den inväntar texten RA, RB eller RC innan data börjar
		averageVoltA = 0;								// samlas in för att skapa en kalibrering och ett polynom
		averageVoltB = 0;
		vDiff = 0;
		averageData(averageVoltA, averageVoltB, vDiff);  		// mät obalansen medelvärdesbilda en aning
		adjustAlert(vDiff);                     	 	 			// skicka obalansspänning till Java-dator
		if (Serial.available() > 0){                     				// kommando sänt? Avbryt balanstrimmning av brygga?
			if(Serial.read() == WHILE_LOOP_BREAK){       		// 127 avbryter while-loop
				breakFlag = false;
			}
		}
	}
}
/*
 * Används för att kontinuerlig mäta bryggans spänning.
 * Fungerar som en voltmeter i Java-GUI.
 * En kvittens på valt menyalternativ skickas till Javadatorn
 * som därefter börjar presentera aktuell spänning i sitt GUI
 */

void measure(){
	bool breakFlag = true;
	double averageVoltA;
	double averageVoltB;
	double vDiff;
	Serial.write("M");									// Java-datorn skannar data från Arduino mha
	Serial.write("\n");									// java.util.Scanner.Scanner(InputStream source)
	while(breakFlag){
		averageVoltA = 0;
		averageVoltB = 0;
		vDiff = 0;
		averageData(averageVoltA, averageVoltB, vDiff);  		// mät obalansen medelvärdesbilda en aning
		adjustAlert(vDiff);                     	 	 			// skicka obalansspänning till Java-dator
		if (Serial.available() > 0){                     				// kommando sänt? Avbryt balanstrimmning av brygga?
			if(Serial.read() == WHILE_LOOP_BREAK){       		// 127 avbryter while-loop
				breakFlag = false;
			}
			delay(100);
		}
	}
}

/*
 * En loop som mäter obalansen i NTC-mätbryggan.
 * Upplösningen är 5/1024 = 4.883 mV per bit
 * Två spänningar från två ADC-ingångar mäts och medelvärdesbildas.
 * Sedan tas differensen av dessa spänningar och utifrån denna differens
 * avgörs om bryggan anses vara i balans/nolltrimmad. Arduino skickar
 * differensen till Java-datorn i form av antalet bitar (0 till 1023)
 * Ex. 2 bitar ger 2*4.8876 = 9.78mV
 *
 * Loopen avbryts manuellt från GUI med tryck på en knapp.
 */ /*
void bridgeZeroAdjust(){
	bool breakFlag = true;
	double averageVoltA;
	double averageVoltB;
	double vDiff;										// Java-datorn skannar data från Arduino mha
	Serial.write("ZERO");									// java.util.Scanner.Scanner(InputStream source)
	Serial.write("\n");									// Den inväntar texten ZERO innan data börjar
	while(breakFlag){									// samlas in
		averageVoltA = 0;
		averageVoltB = 0;
		vDiff = 0;
		averageData(averageVoltA, averageVoltB, vDiff);  		// mät obalansen medelvärdesbilda en aning
		adjustAlert(vDiff);                     	 	 			// skicka obalansspänning till Java-dator
		if (Serial.available() > 0){                     				// kommando sänt? Avbryt balanstrimmning av brygga?
			if(Serial.read() == WHILE_LOOP_BREAK){       		// avbryter while-loop ( < 256 pga byte)
				breakFlag = false;
			}
		}
	}
}
*/
/*
 * Argumenten voltA, voltB och voltDiff är call by reference
 * Två spänningar från två ADC-ingångar mäts och medelvärdesbildas.
 * Skillnaden mellan dessa spänningar är obalansspänningen i bryggan.
 * Upplösningen är 5/1023 = 4.89 mV per bit
 * Beräkning av spänning sker i Java-datorn
 */
void averageData(double& voltA, double& voltB, double& voltDiff){
	double sumA = 0;
	double sumB = 0;
	for(int i = 0; i < NUMBER_OF_SAMPLES; i++){
		sumA += analogRead(analogPinA);					// A/D-omv. tar 100us
		delayMicroseconds(25);
		sumB += analogRead(analogPinB);
		delayMicroseconds(25);
	}
	voltA = (sumA/NUMBER_OF_SAMPLES);
	voltB = (sumB/NUMBER_OF_SAMPLES);
	voltDiff = voltA - voltB;
}

/*
 * Skicka obalansvärdet från A/D-omvandlarna i form av antal bitar obalans.
 * Varje bit motsvarar 5/1023 = 0.004888 V
 * I GUI indikeras att bryggan är balanstrimmad.
 */
void adjustAlert(double voltageDiff){
	Serial.println(avrunda(voltageDiff));
}
/*
 * Mäter temperaturen på värmeelementet och spänningen från bryggan.
 * Temperaturen skickas som ett värde i celcius till Java-datorn
 * och spänningen skickas som ett bitvärde där varje bit motsvarar
 * 5/1023 = 0.004888 V. Detta bitvärde omvandlas till en spänning
 * i Java-datorn och omvandlas därefter till ett motståndsvärde.
 */
void ntcMeasurement(){
	double averageVoltA;
	double averageVoltB;
	double vDiff;
	bool loop = true;
	Serial.write("START");
	Serial.write("\n");
	while (loop) {
		averageVoltA = 0;
		averageVoltB = 0;
		vDiff = 0;
		averageData(averageVoltA, averageVoltB, vDiff); 		// mät obalansen medelvärdesbilda en aning
		Serial.print(getCelcius());							// skicka aktuell temperatur till Javadator
		Serial.print(" ");
		Serial.print(avrunda(vDiff));						// skicka obalansvärdet från A/D-omvandlarna till Javadator
		Serial.print("\n");
		if (Serial.available() > 0){      						// kommando sänt?
			if(Serial.read() == WHILE_LOOP_BREAK){     		// avbryter while-loop
				loop = false;
			}
		}
		delay(111);
	}
}
/*
 * Avrunda en double till ett heltal
 */
int avrunda(double number){
	return static_cast<int>(floor(number + 0.5));
}
void setCelcius(int temp){
	celcius = temp;
}

int getCelcius(){
	return static_cast<int>(floor(max.temperature(RNOMINAL, RREF) + 0.5));
}

Skriv svar