Mätapplikation med Arduino och Java

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

Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Jag påbörjade en tråd med lite frågor om mätinsamling.
Då jag nu kommit igång lägger jag in det hela som ett projekt.

Projektet går ut på att få en Arduino Uno att slå igång ett
värmeelement och mäta temperaturen på värmeelementet.

På värmeelemetet monterar jag också ett NTC-motstånd vars
resistans Arduinon ska mäta parallellt med uppvärmningen.

Tanken är att Arduinon ska leverera två mätvärden, temperatur
och NTC-resistans via serieporten till datorn. Jag tänker mig
att få ett mätvärde på NTC-resistansen vid varje hel grad upp
till en viss temperaturgräns där mätningen avslutas.

På datorn snurrar ett Java-program som tar emot varje mätvärdespar
och skriver dessa till en textfil. Textfilen får formen av två
kolumner med temperatur och ohm-värde.

Exempel...

24 500
25 497
26 492
....osv.

En annan programvara jag har kan sedan läsa den här filen
och plotta en kurva samt kurvanpassa.
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Har skissat på ett Java-GUI och det kommer se ut ungefär så här...
eventuellt tänkte jag ta med en timer/klocka så man kan se hur lång
tid som mätningen pågått.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Den här koden använder jag som test mot Arduino som snurrar en loop för att
efterlikna insamlade mätvärden. Nästa steg blir att få Arduinon att utföra
riktiga mätningar och eftersom jag är helt ny på Arduino så blir det nog
en del labbande där för att få till det. Men det finns ju en uppsjö av exempel
på nätet så det borde gå bra.

Jag har lagt in en funktion som sänder till Arduinon och avbryter mätloopen som
t.ex. använd om man trycker på STOPP-knappen.

Kod: Markera allt

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Scanner;
import com.fazecast.jSerialComm.SerialPort;

public class SerialMainScanner {

	public static void main(String[] args) throws InterruptedException {

		boolean ArduinoFlag = false;
		int AUnoIndex = -1;
		SerialPort serialPort = null;
		Scanner arduinoScanIn = null;
		DataOutputStream javaToArduinoOut = null;
		TextFile textFile = new TextFile();										// TextFile-objekt vars metoder nu kan nås
		String data = new String();												// textsträng att lagra inläst data i
		String breakValue = new String("48");								    // avbryter mätning vid uppnått värde
		int breakIntValue = Integer.parseInt(breakValue);					    // konvertera till heltal
		boolean stopSignal = true;											    // signal som skickas till Arduino
		int delimiterIndex;
		textFile.setTextFileName("data.txt");								    // namn på fil att lagra data i

		SerialPort[] sp = SerialPort.getCommPorts();

		System.out.println("Antal tillgängliga seriella portar: "+sp.length);
		for(int j=0;j<sp.length;j++) {
			System.out.println(sp[j].getDescriptivePortName()+" öppen = "+sp[j].isOpen());
			if(sp[j].getDescriptivePortName().contains("Arduino Uno")){
				ArduinoFlag = true;
				AUnoIndex = j;
			}
		}
		if(ArduinoFlag) {			
			serialPort = sp[AUnoIndex];	
			if(serialPort.isOpen()) {
				serialPort.closePort(); 										// Close connection
			}
			if(!serialPort.isOpen()) {
				serialPort.openPort(); 											// Open connection
			}			
			Thread.sleep(500);
			serialPort.clearDTR();												// Arduino Reset - Starta en mätinsamling

			serialPort.setBaudRate(19200);										// Ställ in baudrate
			serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2500, 0);	// Vänta antal ms på att data ska anlända 						
			System.out.println(serialPort.getDescriptivePortName()+ " öppnad = "+serialPort.isOpen());
			System.out.println();
			System.out.println("==== NTC Measurement Application Januari 2019 ====");
			if((serialPort.bytesAvailable()>0)) {
				try
				{	
					javaToArduinoOut = new DataOutputStream(serialPort.getOutputStream()); // se till att det går skicka data till Arduino
					arduinoScanIn = new Scanner(serialPort.getInputStream());	// se till att det går ta emot data från Arduino
					arduinoScanIn.useDelimiter(" ");					   		// två datavärden levereras med blanksteg emellan 					
					System.out.println(arduinoScanIn.findInLine("START")); 		// startmeddelande från Arduino
					arduinoScanIn.nextLine();							   		// hoppa över nyrads-tecken /n
				}
				catch(IllegalStateException  e)
				{
					e.printStackTrace();
				}
				textFile.createTextFile();										// skapa en textfil
				while(arduinoScanIn.hasNextLine())								// loopa så länge det finns data i skannern
				{			
					try
					{
						data = arduinoScanIn.nextLine();								
						System.out.println(data);
						textFile.writeToFile(data);
						delimiterIndex = data.indexOf(" ");							 // ta reda på vart blanktecknet befinner sig
						try {														 // innan blanktecknet finns temperaturvärdet
							if(Integer.parseInt(data.substring(0, delimiterIndex)) % breakIntValue == 0){ 
								System.out.println("===========================");	 // stämmer det med temeraturbrytvärdet så....
								try {
									javaToArduinoOut.writeBoolean(stopSignal);		 // avbryt mätning
									while(arduinoScanIn.hasNextLine()) {			 // om arduino skickar extra
										System.out.println(arduinoScanIn.nextLine());// strängar (fyllt på skannern) så
									}												 // ta inte med dessa, Integer.parseInt
								}													 // får problem med sånt
								catch(IOException e) {									
								}								
							}
						}
						catch(NumberFormatException e) {
							e.printStackTrace();							
						}
					}
					catch(IllegalStateException e)
					{
						e.printStackTrace();
					} 
				}
				arduinoScanIn.close();											     // stäng scanner
				textFile.closeFileOutputStream();									 // stäng textfil
			}			
			if(serialPort.isOpen()) {
				serialPort.closePort();												 // stäng serieport
				System.out.println("Java Closed The Serial Port!");
			}		
			System.out.println("End from Java!");			
		}		
	}
}

Arduinokod...

Kod: Markera allt

// the setup function runs once when you press reset or power the board
int celcius = 24;
int ohm = 500;
boolean flag = true;
int inByte = 0;         // incoming serial byte

void setup() {
  Serial.begin(19200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB
  }
}
void loop() {
  if (flag) {
    Serial.write("START");
    Serial.write("\n");
    flag = false;
  }
  while (celcius < 101) {
    Serial.print(celcius);
    Serial.write("  ");
    Serial.print(ohm);
    Serial.write('\n');
    delay(200);
    celcius++;
    ohm = -5.9 * celcius + 635;
    if (Serial.available() > 0) {
      if(Serial.read()){          // om en boolean true skickats så avsluta
          celcius = 101;
      }
    }
  }
  Serial.write("End from Aurdino!\n");
  Serial.write("NTC measurement Terminated!\n");
  Serial.end();  
}
Fransson
Inlägg: 509
Blev medlem: 20 maj 2006, 12:27:55
Skype: magnusfransson1
Ort: Bagarmossen (sthlm)

Re: Mätapplikation med Arduino och Java

Inlägg av Fransson »

Mycket intressant!

Det du gör har tydliga paralleller med ett projekt som jag har kört fast i.
Men du har börjat med kommunikationen (och verkar ha något som "fungerar"), vilket är var jag har kört fast.

Jag mäter dock bara 3-4st spänningar och "skalar" dem med hjälp av map() funktionen.

Det jag har kört fast i, är "styrningen" från PCn, till Arduinon. (Vill bland annat överföra nya kalibreringsvärden och ett "nödstopp" kommando.)

Kan jag "låna" din kod och experimentera med?

Med vänliga hälsningar Magnus Fransson.
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Går bra.
En sak som inte fungerade bra ihop med GUI är processen att seriekommunisera med Arduino och
skyffla data till en fil. GUI fryser och kontrollknapparna blir omöjliga att klicka på.

Jag blev tvungen att placera den funktionen i en tråd.

Att sedan via en trådkontroller skicka en signal från GUI till tråden utförs genom
att interrupta trådkontrollern som i sin tur meddelar serie/arduino-objektet med
en interrupt. Fungerar bra.

Åt andra hållet var det till börja med inte lika enkelt tills jag läste om hur man
utför detta i samband med SWT-komponenter.

Jag vill ha en display i GUI som visar aktuell temperatur och NTC och de data finns
ju i tråden.

Det går att fixa med GUI och funktionalitet hos "mätinstrumentet" bra länge, tex skulle
man kunna tänka sig att först värma upp ett metallblock, slå ifrån värmeelementet vid
satt temperatur och påbörja mätning.

En sak som jag kanske ska lägga till är att skriva timervärde och metallblockets temperatur
till en annan fil parallellt, inget som har med NTC-resistansen att göra direkt men mer
som en möjlighet att mäta en kylares egenskaper. Går ju då ta fram en avsvalningskurva.

Så här ser det ut, eventuellt ska jag addera en klocka...
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Seriekommiunikationsklassen som dessutom skriver data till en fil.

Den här koden gör att man kan skicka data från tråden till SWT-GUI.
Exempel...
display.asyncExec (new Runnable () {
public void run () {
window.btnExit.setEnabled(true);
}
});

Kod: Markera allt

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Scanner;
import org.eclipse.swt.widgets.Display;
import com.fazecast.jSerialComm.SerialPort;

/*
 * Klassen representerar en seriell com-port där Arduino finns ansluten. 
 */
public class Serial implements Runnable{
	private int baudRate;								// serieportens i GUI valda överföringshastighet
	boolean stopSignal;									// signal som skickas till Arduino så den kan avbryta mätloopen
	private int breakTempValue;							// temperatur då mätning ska avbrytas, anges i GUI
	private int delimiterIndex;							// använd för att söka efter temperatur då mätning ska avbrytas
	private TextFile textFile = null;					// instans skapas i metoden startSerial()
	private SerialPort serialPort = null; 				// instans skapas i metoden comPortSetUp()
	private DataOutputStream javaToArduinoOut = null;	// instans skapas i metoden scanAndWriteData()
	private Scanner arduinoScanIn = null;			// produces values scanned from the specified input stream
	private NTC window;
	private Display display;
	private String data = null;

	/*
	 * Konstruktor till objekt av typen Serial
	 * Ett objekt av denna klass skapas i klassen som innehåller main 
	 * Detta objekt ger tillgång till metoden run() som anropar startSerial(TextFile textfile) som
	 * påbörjar en kommunikation med Arduino och lagrar data från denna i en textfil.
	 * Vid tryck på knappen START i GUI anropas startSerial(TextFile textfile)
	 */
	public Serial(NTC window, Display display) {
		this.window = window;
		this.display = display;
	}

	public void run() {
		try {
			startSerial(NTC.getTextFile());

		} catch (InterruptedException e) {
			System.out.println("InterruptedException in Serial run()");
		}
	}

	/*
	 * I GUI kan en temperatur väljas där mätningen ska avbrytas.
	 * Default är angivet i en klassvariabel
	 */
	public void setBreakTemp(int breaktemp) {
		breakTempValue = breaktemp;
	}
	/*
	 * Returnerar aktuellt satt stopp/avbryt temperatur
	 */
	public int getBreakTemp() {
		return breakTempValue;
	}

	/*
	 * I GUI kan olika baudrate väljas. Default är 9600bps
	 * Metoden sätter valt värde.
	 */
	public void setBaudRate(int baudrate) {
		baudRate = baudrate;
	}

	/*
	 * Returnerar aktuellt satt baudrate
	 */
	public int getBaudRate() {
		return baudRate;
	}

	/*
	 * Påbörjar en kontakt med den COM-port som Arduino är ansluten till och
	 * när kontakt är upprättad påbörjas datainsamling från Arduino.
	 * Via GUi finns alternativa val för baudrate. Denna metod anropas
	 * vid tryck på knappen START i GUI.
	 */
	private void startSerial(TextFile textfile) throws InterruptedException {
		textFile = textfile;							// referens till ett objekt av typen TextFile som skapats i GUI
		boolean flag = this.comPortSetUp();				// konfigurerar porten

		if(flag) {
			this.scanAndWriteData();					// läs indata och skriv till textfil
		}			
	}

	/*
	 * Metod. Scannar av vilka COM-portar som finns tillgängliga och om Arduino är ansluten
	 * till någon av dessa. Port med Arduino öppnas och porten konfigureras. Baudrate väljs i GUI.
	 * 
	 * @return Ett SerialPort objekt som håller porten till Arduino annars null.
	 * @throws InterruptedException
	 */
	public boolean comPortSetUp() throws InterruptedException {

		boolean AUnoFlag = false;
		int AUnoIndex = -1;	
		SerialPort[] sp = SerialPort.getCommPorts();		
		System.out.println("Antal tillgängliga seriella portar: "+sp.length);				
		for(int j=0;j<sp.length;j++) {
			System.out.println(sp[j].getDescriptivePortName()+" öppen = "+sp[j].isOpen());
			if(sp[j].getDescriptivePortName().contains("Arduino Uno")){
				AUnoFlag = true;
				AUnoIndex = j;
			}
		}
		if(AUnoFlag) {
			serialPort = sp[AUnoIndex];	
			if(serialPort.isOpen()) {
				serialPort.closePort(); 							// Close connection
			}
			if(!serialPort.isOpen()) {
				serialPort.openPort(); 								// Open connection
			}			
			Thread.sleep(500);
			serialPort.clearDTR();									// Arduino Reset			
			serialPort.setBaudRate(this.getBaudRate());
			serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2500, 0);
			
			System.out.println(serialPort.getDescriptivePortName()+ " öppnad = "+serialPort.isOpen());			
		}		
		return AUnoFlag;
	}

	/*
	 * Metod. Läser in data från Arduino som skickas på serieporten och skriver ut data
	 * till en display i GUI samt till en textfil. Data skrivs i textfilen i två kolumner,
	 * temperatur och NTC-ohm-värde. Inläsning avslutas antingen då en default-temperatur
	 * uppnåtts eller då en valbar temperatur som angivits i GUI uppnås. Sedan stängs
	 * skannern, textfilen och serieporten.
	 */
	public void scanAndWriteData() {
		textFile.createTextFile();				// skapa en namngiven textfil att lagra inskannad data i		
		

		System.out.println("Temperatur där mätning ska avbrytas: "+this.getBreakTemp());
		System.out.println("====== NTC Measurement Application Januari 2019 =======");
		if((serialPort.bytesAvailable()>0)) {
			try
			{	
				javaToArduinoOut = new DataOutputStream(serialPort.getOutputStream());				
				arduinoScanIn = new Scanner(serialPort.getInputStream());
				arduinoScanIn.useDelimiter(" ");					
				System.out.println(arduinoScanIn.findInLine("START"));
				arduinoScanIn.nextLine();
			}
			catch(IllegalStateException  e)
			{
				e.printStackTrace();
			}
			while(arduinoScanIn.hasNextLine())
			{				
				try
				{
					if(Thread.interrupted()) {
						try {													// så dess mätloop avslutas
							javaToArduinoOut.writeBoolean(true); 				// avbryt mätning skicka signal
							while(arduinoScanIn.hasNextLine()) {				// om arduino skickar extra
								arduinoScanIn.nextLine();						// strängar så ta inte med dessa							
							}
							break;												// hoppa ur loopen vid "nödstopp"
						}													  
						catch(IOException e) {							
						}									
					}
					data = arduinoScanIn.nextLine();					
					System.out.println(data);
					textFile.writeToFile(data);									// skriv data till textfil
					
					display.asyncExec (new Runnable () {						// uppdatera temp- och ntc-display i GUI
						public void run () {
							window.changeLedDisplay(data);
						}
					});
										
					delimiterIndex = data.indexOf(" ");							// avbryt mätning om användardefinierad
					try {														// stopptemperatur uppnåtts
						if(Integer.parseInt(data.substring(0, delimiterIndex)) % this.getBreakTemp() == 0){		 				 
																				// stoppsignal ska skickas till Arduino
							try {												// så dess mätloop avslutas
								javaToArduinoOut.writeBoolean(true); 			// avbryt mätning
								while(arduinoScanIn.hasNextLine()) {			// om arduino skickar extra
									arduinoScanIn.nextLine();					// strängar så ta inte med dessa
								}
								break;															
							}													  
							catch(IOException e) {									
							}
							System.out.println();
						}
					}
					catch(NumberFormatException e) {
						e.printStackTrace();							
					}
				}
				catch(IllegalStateException e)
				{
					e.printStackTrace();
				}
			}
			arduinoScanIn.close();						// avsluta skannern
			textFile.closeFileOutputStream();			// stäng textfilen
		}			
		if(serialPort.isOpen()) {
			serialPort.closePort();						// koppla ned com-porten
		}
		display.asyncExec (new Runnable () {			// EXIT-knapp i GUI
			public void run () {
				window.btnExit.setEnabled(true);
			}
		});			
		System.out.println("End from Java!");
	}
}
Trådkontrollern....

Kod: Markera allt

public class ThreadController implements Runnable {
	private Thread	arduinoSerialThread;
	private Serial arduinoSerial;
	// The timer interval in milliseconds
	private static final int   TIMER_INTERVAL = 1000;
	public ThreadController() {

	}
	public void run() {
		arduinoSerial = NTC.getArduinoSerial();
		arduinoSerialThread = new Thread(arduinoSerial);
		Thread.currentThread().setName("ControllerThread");
		arduinoSerialThread.start();
		while(true) {
			try {
				Thread.sleep(TIMER_INTERVAL);
			}
			catch(InterruptedException ie) {				
				Thread.currentThread().interrupt();
			}
			if(Thread.interrupted()) {
				arduinoSerialThread.interrupt();
				break;
			}
		}
	}
}

GUI och main......

Kod: Markera allt

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Button;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Spinner;

public class NTC {

	protected static Shell shlNtc;
	private Text txtDatatxt;
	private static final int DEFAULTBREAKTEMP = 100;
	private static final String DEFAULTTEXTFILENAME = "data.txt";
	private static final int DEFAULTBAUDRATE = 19200;
	private static Serial arduinoSerial;
	private ThreadController threadController;
	private Thread threadControllerThread;
	private Button btnStopp;
	public Button btnExit;
	private static TextFile textFile;
	private TempDisplay tempDisplay; 
	private NTCDisplay ntcDisplay;
	private String[] ImgLink = new String[12];
	private CLabel LED_0;	
	private CLabel LED_1;
	private CLabel LED_2;
	private CLabel LED_3;
	private CLabel LED_4;
	private CLabel LED_5;
	private CLabel LED_6;
	private CLabel LED_7;
	private CLabel LED_8;
	private static NTC window;
	private Display display;
	private static final String LED0 = "/LED/LED_GREEN_0.jpg";
	private static final String LED1 = "/LED/LED_GREEN_1.jpg";
	private static final String LED2 = "/LED/LED_GREEN_2.jpg";
	private static final String LED3 = "/LED/LED_GREEN_3.jpg";
	private static final String LED4 = "/LED/LED_GREEN_4.jpg";
	private static final String LED5 = "/LED/LED_GREEN_5.jpg";
	private static final String LED6 = "/LED/LED_GREEN_6.jpg";
	private static final String LED7 = "/LED/LED_GREEN_7.jpg";
	private static final String LED8 = "/LED/LED_GREEN_8.jpg";
	private static final String LED9 = "/LED/LED_GREEN_9.jpg";
	private static final String LEDBLANK = "/LED/LED_GREEN_BLANK.jpg";
	private static final String LEDMINUS = "/LED/LED_GREEN_MINUS.jpg";
	private Composite composite;
	private CLabel lblNewLabel_2;
	private Spinner spinner;


	/**
	 * Launch the application.
	 * @param args
	 */
	public static void main(String[] args) {	
		try {
			window = new NTC();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}		
	}

	/**
	 * Open the window.
	 */
	public void open() {		
		display = Display.getDefault();
		createContents();
		shlNtc.open();
		shlNtc.layout();
		while (!shlNtc.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/*
	 * Diverse Metoder. Vid tryck på knappen START i GUI så påbörjas en NTC-mätning.
	 * Den port Arduino är ansluten till öppnas och konfigureras. En fil
	 * med valbart namn skapas och data från Arduino läses in och lagras
	 * i filen. När mätningen är klar eller har stoppats stängs porten och
	 * filen med data. 
	 */
	private void setUpLEDDisplay() {
		ImgLink[0] = LED0;
		ImgLink[1] = LED1;
		ImgLink[2] = LED2;
		ImgLink[3] = LED3;
		ImgLink[4] = LED4;
		ImgLink[5] = LED5;
		ImgLink[6] = LED6;
		ImgLink[7] = LED7;
		ImgLink[8] = LED8;
		ImgLink[9] = LED9;
		ImgLink[10] = LEDBLANK;
		ImgLink[11] = LEDMINUS;

		LED_0 = new CLabel(shlNtc, SWT.NONE);		// temperatur-display 3st LED
		LED_1 = new CLabel(shlNtc, SWT.NONE);
		LED_2 = new CLabel(shlNtc, SWT.NONE);
		LED_3 = new CLabel(shlNtc, SWT.NONE);		// NTC-display 6st LED
		LED_4 = new CLabel(shlNtc, SWT.NONE);		
		LED_5 = new CLabel(shlNtc, SWT.NONE);
		LED_6 = new CLabel(shlNtc, SWT.NONE);
		LED_7 = new CLabel(shlNtc, SWT.NONE);
		LED_8 = new CLabel(shlNtc, SWT.NONE);
		LED_0.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK)); // bakgrundsbilder i form av 7-seg. LED
		LED_1.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK));
		LED_2.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK));
		LED_3.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK));
		LED_4.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK));
		LED_5.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK));
		LED_6.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK));
		LED_7.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK));
		LED_8.setImage(SWTResourceManager.getImage(NTC.class, LEDBLANK));
		tempDisplay = new TempDisplay();
		ntcDisplay = new NTCDisplay();
	}
	
	private void setTempGUIdisplayValue() {	
		int digit100 = tempDisplay.getLED100Value();
		int digit10 = tempDisplay.getLED10Value();
		int digit1 = tempDisplay.getLED1Value();
		LED_0.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit100]));
		LED_1.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit10]));
		LED_2.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit1]));
	}
	
	private void setNTCGUIdisplayValue() {	
		int digit100000 = ntcDisplay.getLED100000Value();
		int digit10000 = ntcDisplay.getLED10000Value();
		int digit1000 = ntcDisplay.getLED1000Value();
		int digit100 = ntcDisplay.getLED100Value();
		int digit10 = ntcDisplay.getLED10Value();
		int digit1 = ntcDisplay.getLED1Value();		
		LED_3.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit100000]));
		LED_4.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit10000]));
		LED_5.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit1000]));
		LED_6.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit100]));
		LED_7.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit10]));
		LED_8.setImage(SWTResourceManager.getImage(NTC.class, ImgLink[digit1]));
	}
	private void setUpTextFile() {
		textFile = new TextFile();
		textFile.setTextFileName(NTC.DEFAULTTEXTFILENAME);	// default textfilsnamn där insamlad data lagras
	}
	public static TextFile getTextFile() {
		return textFile;
	}
	private void setUpSerial() {
		arduinoSerial = new Serial(window,display);
		arduinoSerial.setBaudRate(NTC.DEFAULTBAUDRATE);		// default baudrate för kommunikation med Arduino
		arduinoSerial.setBreakTemp(NTC.DEFAULTBREAKTEMP);	// default temperatur då mätning ska avbrytas
	}
	public static Serial getArduinoSerial() {
		return arduinoSerial;
	}
	/**
	 * Skapar de objekt som måste ha referenser klara innan createContents()
	 * exekveras fullt ut
	 */
	private void setUpSomeOfTheGUI() {
		btnExit = new Button(shlNtc, SWT.BORDER | SWT.FLAT | SWT.CENTER);
		btnExit.setEnabled(true);
		btnStopp = new Button(shlNtc, SWT.BORDER | SWT.FLAT | SWT.CENTER);
		btnStopp.setEnabled(false);
	}

	/**
	 * Uppdaterar de två 7seg-LED-displayerna i GUI
	 * 
	 * @param data en textsträng på formen "temperatur ntcmotstånd"
	 */
	public void changeLedDisplay(String data) {
		String temp = data.substring(0, data.indexOf(" "));
		String ntc = data.substring(data.indexOf(" ")).trim();
		tempDisplay.setTempValue(Integer.parseInt(temp));
		ntcDisplay.setOhmValue(Integer.parseInt(ntc));
		setTempGUIdisplayValue();				
		setNTCGUIdisplayValue();
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		shlNtc = new Shell();
		shlNtc.setImage(null);
		shlNtc.setForeground(SWTResourceManager.getColor(0, 0, 0));
		shlNtc.setBackground(SWTResourceManager.getColor(0, 102, 102));
		shlNtc.setSize(465, 467);
		shlNtc.setText("Arduino Serial Control Software");
		shlNtc.setLayout(null);

		setUpLEDDisplay();
		setUpTextFile();
		setUpSerial();
		setUpSomeOfTheGUI();

		//----------------------------------------------------------------------------EXIT-knapp
		btnExit.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {				
				System.exit(0);
			}
		});

		btnExit.setText("EXIT");
		btnExit.setForeground(SWTResourceManager.getColor(255, 255, 0));
		btnExit.setFont(SWTResourceManager.getFont("Sitka Display", 15, SWT.BOLD));
		btnExit.setBackground(SWTResourceManager.getColor(0, 0, 0));
		btnExit.setBounds(355, 60, 88, 44);


		//----------------------------------------------------------------------------Info om Baudrate
		Group grpBaudrate = new Group(shlNtc, SWT.NONE);
		grpBaudrate.setEnabled(false);
		grpBaudrate.setBounds(355, 10, 88, 44);
		grpBaudrate.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND));
		grpBaudrate.setFont(SWTResourceManager.getFont("Sitka Display", 12, SWT.BOLD | SWT.ITALIC));
		grpBaudrate.setText("Baudrate");
		grpBaudrate.setLayout(null);

		CLabel lblNewLabel_1 = new CLabel(grpBaudrate, SWT.NONE);
		lblNewLabel_1.setFont(SWTResourceManager.getFont("Segoe UI", 9, SWT.BOLD));
		lblNewLabel_1.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND));
		lblNewLabel_1.setAlignment(SWT.CENTER);
		lblNewLabel_1.setBounds(13, 23, 65, 21);
		lblNewLabel_1.setText("9600bps");


		//----------------------------------------------------------------------------Info. Rubriktext Banner
		CLabel lblNtcMeasurementSoftware = new CLabel(shlNtc, SWT.NONE);
		lblNtcMeasurementSoftware.setForeground(SWTResourceManager.getColor(255, 248, 220));
		lblNtcMeasurementSoftware.setBackground(SWTResourceManager.getColor(0, 0, 139));
		lblNtcMeasurementSoftware.setFont(SWTResourceManager.getFont("Sitka Display", 15, SWT.BOLD));
		lblNtcMeasurementSoftware.setAlignment(SWT.CENTER);
		lblNtcMeasurementSoftware.setBounds(10, 10, 339, 44);
		lblNtcMeasurementSoftware.setText("NTC Measurement  Software");

		CLabel lblAngeTextfilnamnAtt = new CLabel(shlNtc, SWT.NONE);
		lblAngeTextfilnamnAtt.setAlignment(SWT.CENTER);
		lblAngeTextfilnamnAtt.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.BOLD));
		lblAngeTextfilnamnAtt.setBounds(10, 60, 339, 21);
		lblAngeTextfilnamnAtt.setText("Ange textfilnamn att spara data till:");

		//----------------------------------------------------------------------------Textfält för filnamn
		txtDatatxt = new Text(shlNtc, SWT.BORDER);
		txtDatatxt.setText("data.txt");
		txtDatatxt.setFont(SWTResourceManager.getFont("Arial", 9, SWT.NORMAL));
		txtDatatxt.setBounds(10, 87, 339, 21);

		//----------------------------------------------------------------------------Info.skylt startknapp
		CLabel lblAvbrytsVid = new CLabel(shlNtc, SWT.NONE);
		lblAvbrytsVid.setText("Avbryts vid 100 grader Celcius som default");
		lblAvbrytsVid.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.BOLD));
		lblAvbrytsVid.setBackground(SWTResourceManager.getColor(255, 255, 153));
		lblAvbrytsVid.setAlignment(SWT.CENTER);
		lblAvbrytsVid.setBounds(10, 114, 339, 22);

		//----------------------------------------------------------------------------Info.skylt startknapp
		CLabel lblNewLabel = new CLabel(shlNtc, SWT.NONE);
		lblNewLabel.setBackground(SWTResourceManager.getColor(255, 255, 153));
		lblNewLabel.setAlignment(SWT.CENTER);
		lblNewLabel.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.BOLD));
		lblNewLabel.setBounds(10, 136, 339, 22);
		lblNewLabel.setText("Starta Arduino NTC-m\u00E4tning ---->");

		//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> STARTKNAPP
		Button btnStartaArduinoNtcmtning = new Button(shlNtc, SWT.BORDER | SWT.FLAT | SWT.CENTER);
		btnStartaArduinoNtcmtning.addMouseListener(new MouseAdapter() {			
			public void mouseUp(MouseEvent e) {				
				textFile.setTextFileName(txtDatatxt.getText()); 			// hämta text från textfält med filnamn
				threadController = new ThreadController();
				threadControllerThread = new Thread(threadController);		// en tråd får bara startas en gång																		
				try {				
					threadControllerThread.start();							// starta upp NTC-mätning
				}
				catch(IllegalThreadStateException itse) {
					System.out.println("IllegalThreadStateException");
				} 
				btnStopp.setEnabled(true);
				btnStartaArduinoNtcmtning.setEnabled(false);
				btnExit.setEnabled(false);
			}}); 
		btnStartaArduinoNtcmtning.setFont(SWTResourceManager.getFont("Sitka Display", 15, SWT.BOLD));
		btnStartaArduinoNtcmtning.setBackground(SWTResourceManager.getColor(0, 139, 139));
		btnStartaArduinoNtcmtning.setForeground(SWTResourceManager.getColor(255, 255, 0));		
		btnStartaArduinoNtcmtning.setBounds(355, 114, 88, 44);
		btnStartaArduinoNtcmtning.setText("START");

		//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> STOPPKNAPP		
		btnStopp.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {					// signalera Stopp till Arduino-inläsningen
				try {											// avbryt trådkontrollern som i sin tur avbryter
					threadControllerThread.interrupt();			// inäsning av data från Arduinon
				}
				catch(SecurityException se) {
					se.printStackTrace();
				}
				btnStartaArduinoNtcmtning.setEnabled(true);
				btnExit.setEnabled(true);
			}
		});

		btnStopp.setText("STOPP");
		btnStopp.setForeground(SWTResourceManager.getColor(255, 255, 240));
		btnStopp.setFont(SWTResourceManager.getFont("Sitka Display", 15, SWT.BOLD));
		btnStopp.setBackground(SWTResourceManager.getColor(204, 0, 0));
		btnStopp.setBounds(10, 164, 88, 44);

		//----------------------------------------------------------------------------Info.skylt stoppknapp
		CLabel label = new CLabel(shlNtc, SWT.NONE);
		label.setBackground(SWTResourceManager.getColor(255, 255, 153));
		label.setText("<---- Stoppa Arduino NTC-m\u00E4tning");
		label.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.BOLD));
		label.setAlignment(SWT.CENTER);
		label.setBounds(104, 164, 339, 44);

		//----------------------------------------------------------------------------Info.skylt Ange avbryt-temperatur		
		CLabel lblAngeEnTemperatur = new CLabel(shlNtc, SWT.NONE);
		lblAngeEnTemperatur.setLeftMargin(5);
		lblAngeEnTemperatur.setText("Ange en temperatur\r\nf\u00F6r Automatiskt Stopp -->");
		lblAngeEnTemperatur.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.BOLD));
		lblAngeEnTemperatur.setBackground(SWTResourceManager.getColor(255, 255, 153));
		lblAngeEnTemperatur.setBounds(10, 214, 203, 44);

		//----------------------------------------------------------------------------Info.skylt avbryt-temperatur range
		CLabel lblGrader = new CLabel(shlNtc, SWT.NONE);
		lblGrader.setAlignment(SWT.CENTER);
		lblGrader.setText("50 grader till 150 grader");
		lblGrader.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.BOLD));
		lblGrader.setBackground(SWTResourceManager.getColor(255, 255, 153));
		lblGrader.setBounds(219, 214, 187, 21);
		spinner = new Spinner(shlNtc, SWT.BORDER);
		spinner.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.NORMAL));
		spinner.setMaximum(150);
		spinner.setMinimum(50);
		spinner.setSelection(100);
		
		
		spinner.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				spinner.getSelection();
			}
		});
		
		
		//-----------------------------------------------------------------------------Spinner
		spinner.setBounds(219, 237, 62, 21);

		CLabel lblgraderCelsius = new CLabel(shlNtc, SWT.NONE);
		lblgraderCelsius.setText(" [grader Celsius]");
		lblgraderCelsius.setForeground(SWTResourceManager.getColor(240, 230, 140));
		lblgraderCelsius.setFont(SWTResourceManager.getFont("Segoe UI", 9, SWT.BOLD));
		lblgraderCelsius.setBackground(SWTResourceManager.getColor(0, 0, 0));
		lblgraderCelsius.setAlignment(SWT.CENTER);
		lblgraderCelsius.setBounds(277, 237, 129, 21);

		CLabel lblKryssaIOm = new CLabel(shlNtc, SWT.NONE);
		lblKryssaIOm.setLeftMargin(5);
		lblKryssaIOm.setText("Bekr\u00E4fta Automatiskt Stopp ->");
		lblKryssaIOm.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.BOLD));
		lblKryssaIOm.setBackground(SWTResourceManager.getColor(255, 255, 153));
		lblKryssaIOm.setBounds(10, 264, 203, 27);
		composite = new Composite(shlNtc, SWT.NONE);
		lblNewLabel_2 = new CLabel(composite, SWT.CENTER);
		
				//---------------------------------------------------------------------------------------- Checkruta
				composite.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT));
				composite.setBounds(219, 264, 224, 27);
				
						Button btnCheckButton = new Button(composite, SWT.CHECK);
						btnCheckButton.setSelection(false);
						btnCheckButton.addSelectionListener(new SelectionAdapter() {
							@Override
							public void widgetSelected(SelectionEvent e) {
								Button source =  (Button) e.getSource();
								if(source.getSelection())  { 											// inmatad temperaturgräns konverteras till int	
									try {
										btnCheckButton.setSelection(true);
										spinner.setEnabled(false);
									//	int intValue = (int) Math.round(Double.parseDouble(text_1.getText()));
										int intValue = spinner.getSelection();
										if(intValue<50) {
											lblNewLabel_2.setText(""+50);
											spinner.setSelection(50);
											arduinoSerial.setBreakTemp(50);
										}
										else if(intValue>150) {
											lblNewLabel_2.setText(""+150);
											spinner.setSelection(150);
											arduinoSerial.setBreakTemp(150);
										}
										else {
											lblNewLabel_2.setText(""+intValue);
											arduinoSerial.setBreakTemp(intValue);				// användardefinierat mätstopp tillämpas
										}
									}
									catch(NumberFormatException nfe) {							// om annat än ett tal knappas in så återställ textfältet
										btnCheckButton.setSelection(false);
										spinner.setSelection(DEFAULTBREAKTEMP);
										lblNewLabel_2.setText(""+DEFAULTBREAKTEMP);
									}
								}
								else if(!source.getSelection())  {
									btnCheckButton.setSelection(false);
									spinner.setEnabled(true);
									spinner.setSelection(DEFAULTBREAKTEMP);
									lblNewLabel_2.setText(""+DEFAULTBREAKTEMP);
									arduinoSerial.setBreakTemp(DEFAULTBREAKTEMP);
								}

							}
						});
						btnCheckButton.setLocation(5, 0);
						btnCheckButton.setSize(68, 27);
						btnCheckButton.setFont(SWTResourceManager.getFont("Segoe UI", 9, SWT.BOLD));
						btnCheckButton.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT));
						btnCheckButton.setText("Markera");
						
								lblNewLabel_2.setBackground(SWTResourceManager.getColor(0, 0, 0));
								lblNewLabel_2.setForeground(SWTResourceManager.getColor(240, 230, 140));
								lblNewLabel_2.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.BOLD));
								lblNewLabel_2.setBounds(75, 0, 49, 27);
								lblNewLabel_2.setText("100");
								
										CLabel label_1 = new CLabel(composite, SWT.NONE);
										label_1.setText(" [grader Celsius]");
										label_1.setForeground(SWTResourceManager.getColor(240, 230, 140));
										label_1.setFont(SWTResourceManager.getFont("Segoe UI", 9, SWT.BOLD));
										label_1.setBackground(SWTResourceManager.getColor(0, 0, 0));
										label_1.setAlignment(SWT.CENTER);
										label_1.setBounds(123, 0, 101, 27);

		//----------------------------------------------------------------------------Info.skylt Rubrik Aktuell Mätdata
		CLabel lblAktuellMtdata = new CLabel(shlNtc, SWT.BORDER | SWT.SHADOW_IN | SWT.SHADOW_OUT | SWT.CENTER);
		lblAktuellMtdata.setForeground(SWTResourceManager.getColor(0, 0, 128));
		lblAktuellMtdata.setBackground(SWTResourceManager.getColor(SWT.COLOR_INFO_BACKGROUND));
		lblAktuellMtdata.setFont(SWTResourceManager.getFont("Courier", 17, SWT.BOLD));
		lblAktuellMtdata.setBounds(10, 297, 433, 35);
		lblAktuellMtdata.setText("A k t u e l l  M \u00E4 t d a t a");

		//----------------------------------------------------------------------------Info.skylt Rubrik Temperatur [Celsius]
		CLabel lblTemperatur = new CLabel(shlNtc, SWT.NONE);
		lblTemperatur.setForeground(SWTResourceManager.getColor(240, 230, 140));
		lblTemperatur.setBackground(SWTResourceManager.getColor(0, 0, 0));
		lblTemperatur.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.BOLD));
		lblTemperatur.setAlignment(SWT.CENTER);
		lblTemperatur.setBounds(10, 338, 182, 34);
		lblTemperatur.setText("Temperatur [Celsius]");

		//----------------------------------------------------------------------------Info.skylt Rubrik NTC [ohm]
		CLabel lblNtcohm = new CLabel(shlNtc, SWT.NONE);
		lblNtcohm.setText("NTC [ohm]");
		lblNtcohm.setForeground(SWTResourceManager.getColor(240, 230, 140));
		lblNtcohm.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.BOLD));
		lblNtcohm.setBackground(SWTResourceManager.getColor(0, 0, 0));
		lblNtcohm.setAlignment(SWT.CENTER);
		lblNtcohm.setBounds(238, 338, 205, 34);

		//----------------------------------------------------------------------------LED-display Temperatur
		LED_0.setText("");
		LED_0.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_0.setBounds(96, 378, 28, 44);

		LED_1.setText("");
		LED_1.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_1.setBounds(130, 378, 28, 44);

		LED_2.setText("");
		LED_2.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_2.setBounds(164, 378, 28, 44);

		//----------------------------------------------------------------------------LED-display NTC
		LED_3.setText("");
		LED_3.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_3.setBounds(238, 378, 28, 44);

		LED_4.setText("");
		LED_4.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_4.setBounds(278, 378, 28, 44);

		LED_5.setText("");
		LED_5.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_5.setBounds(313, 378, 28, 44);

		LED_6.setText("");
		LED_6.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_6.setBounds(347, 378, 28, 44);

		LED_7.setText("");
		LED_7.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_7.setBounds(381, 378, 28, 44);

		LED_8.setText("");
		LED_8.setBackground(SWTResourceManager.getColor(0, 0, 0));
		LED_8.setBounds(415, 378, 28, 44);
	}
}

Textfils-klassen...

Kod: Markera allt

import java.io.PrintWriter;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
/*
 * Klassen representerar en öppnad textfil att skriva data till
 */
public class TextFile {
	private PrintWriter outputStream = null;
	private String textFileName = "data.txt";

	/*
	 * Konstruktor till ett objekt av typen TextFileOutput.
	 * Ett objekt av denna klass skapas i klassen som innehåller main 
	 */
	public TextFile() {

	}

	/*
	 * En fil öppnas och namnges enligt vad som angivits i GUI eller default
	 */
	public void createTextFile() {		
		try {
			outputStream = new PrintWriter(new FileOutputStream(this.getTextFileName()));
		}
		catch(FileNotFoundException e){
			System.out.println("Error opening the file");
			System.exit(0);
		}
	}

	/*
	 * Metod som skriver data till en öppnad och namngiven textfil.
	 */
	public void writeToFile(String data)
	{
		outputStream.println(data);
		outputStream.flush();		
	}

	/*
	 * Metod som stänger ned en öppnad textfil
	 */
	public void closeFileOutputStream()
	{
		outputStream.close();
	}

	/*
	 * I GUI kan textfilen dit data skrivs namnges.
	 * Default är data.txt
	 */
	public void setTextFileName(String name) {
		textFileName = name;
	}

	/*
	 * Returnerar aktuellt namn på datatextfilen där data ska lagras
	 */
	public String getTextFileName() {
		return textFileName;
	}
}

Temperatur-displayen (NTC är nästan samma fast med 6 siffror)...

Kod: Markera allt

/**
 * @author 4kTRB
 * 
 * Denna klass implementerar en digital temperatur-display i form av en
 * tresiffrig 7-segments LED
 */
public class TempDisplay{

	private DigitDisplay LED100;
	private DigitDisplay LED10;
	private DigitDisplay LED1;
	private String displayStringLED100;
	private String displayStringLED10;
	private String displayStringLED1;
	private static final int BLANK = 10;
	private static final int MINUS = 11;

	/*
	 * Konstruktor för TempDisplay-objekt.
	 * Skapar en ny temperaturdisplay som representerar tre 7-segments LED
	 * Klassen har metoder för att hantera vad som ska visas i temperaturdisplayen
	 * Själva displayen finns i GUI i form av bilder inlagda i CLabels.
	 */
	public TempDisplay() {
		LED100 = new DigitDisplay();				// 100-tal
		LED10 = new DigitDisplay();					// 10-tal
		LED1 = new DigitDisplay();					// 1-tal
	}
	/**
	 * Åtkomst av de individuella 7-segments LED
	 * @return
	 */
	public int getLED100Value() {
		return LED100.getValue();
	}
	public int getLED10Value() {
		return LED10.getValue();
	}
	public int getLED1Value() {
		return LED1.getValue();
	}
	/*
	 * Sätter temperaturen på displayen
	 * Displayen i GUI ändras ej. GUI har en egen metod
	 * för detta.
	 */
	public void setTempValue(int temp) {		
		int length = String.valueOf(temp).length();
		if(temp<0) {									// minusgrader
			length = length-1;							// räkna bort minustecken
			temp = Math.abs(temp);
			if(length==1) {
				LED100.setValue(BLANK);
				LED10.setValue(MINUS);		
				LED1.setValue(temp);
			}
			if(length==2) {
				LED100.setValue(MINUS);
				LED10.setValue(temp/10);
				LED1.setValue(temp%10);
			}			
		}
		else {
			if(length==1) {
				LED100.setValue(BLANK);
				LED10.setValue(BLANK);		
				LED1.setValue(temp);
			}
			if(length==2) {
				LED100.setValue(BLANK);
				LED10.setValue(temp/10);
				LED1.setValue(temp%10);
			}
			if(length==3) {
				LED100.setValue(temp/100);
				LED10.setValue(temp%100/10);
				LED1.setValue(temp%100%10);
			}
		}
	}

	/*
	 * Returnerar aktuell temperatur som visas på displayen
	 */
	public String getTempValue() {
		displayStringLED100 = ""+LED100.getDisplayValue();
		displayStringLED10 = ""+LED10.getDisplayValue();
		displayStringLED1 =  ""+LED1.getDisplayValue();
		return displayStringLED100+displayStringLED10+displayStringLED1;
	}
}

och så klassen som representerar en 7-seg LED...

Kod: Markera allt

/**
 * @author 4kTRB
 * Klassen representerar en digital nummerdisplay som kan hålla en siffra 0-9
 */
public class DigitDisplay {
	private int tempValue;
	/*
	 * KOnstruktor för objekt av klassen TempDigitDisplay
	 */
	public DigitDisplay() {
		tempValue = 10;
	}
	/*
	 * Returnera displayens aktuella värde.
	 */
	public int getValue() {
		return tempValue;
	}
	/*
	 * Sätter displayen till önskat värde.
	 */
	public void setValue(int replacementValue) {
		tempValue = replacementValue;
	}
	/*
	 * Returnerar displayvärdet i form av en sträng.
	 */
	public int getDisplayValue() {
		return tempValue;
	}
}
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Textfilen och eclipse-konsolen.

Ska börja labba med Arduinon och en dallas-tempsensor snart.
Måste sätta mig in i lite basic C++ vad det verkar som... :cry:
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Den där Dallas-sensorn är inte gjord för högre temperaturer
så jag får tänka om. Funderade på en PT100
https://www.energibutiken.se/sv/29-pt100
Det blir mer pyssel med elektronik runt elementet.
https://www.instructables.com/id/Readin ... g-Arduino/

Edit:
Eller en sån här
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Implementerade en timer.
Måste nog lägga till ett val där tid och temperatur finns med i en separat fil.
Sedan om jag vill ha en avsvalningskurva så måste elementet först värmas
och sedan logga tempen tills det svalnat.
:)
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Labbade med att försöka tända och släcka den inbyggda lysdioden på Arduino UNO-kortet
och upptäckte några programvaruförbättringar att applicera på NTC-projektet.
Varje gång man klickar på switch-knappen tänds eller släcks lysdioden.
Det här är ju ganska coolt tycker jag. :)

Kör den här koden på Arduinon:

Kod: Markera allt

void setup() {
  pinMode(LED_BUILTIN, OUTPUT); 
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.begin(19200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB
  }  
}
void loop() {
  if (Serial.available() > 0) {
    if (Serial.read()) {                  // om en boolean true skickats så LED = High
      digitalWrite(LED_BUILTIN, HIGH);
    }
    else {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
}
Skapade ett gui med 3 knappar...
LED_controller_GUI.png

Kod: Markera allt

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;

public class AppWin {
	private static final int DEFAULTBAUDRATE = 19200;
	private static AppWinThreadController threadController;
	private static Thread threadControllerThread;
	private static AppWinSerial appwinSerial;

	private static void setUpSerial() {
		appwinSerial = new AppWinSerial();
		appwinSerial.setBaudRate(AppWin.DEFAULTBAUDRATE);		// default baudrate för kommunikation med Arduino
	}

	public static AppWinSerial getAppWinSerial() {
		return appwinSerial;
	}

	/**
	 * Launch the application.
	 * @param args
	 */
	public static void main(String[] args) {
		Display display = Display.getDefault();
		Shell shell = new Shell();
		shell.setSize(239, 169);
		shell.setLocation(800, 200);
		shell.setText("SWT Application");

		AppWin.setUpSerial();

		//----------------------------------------------------------------START
		Button btnNewButton = new Button(shell, SWT.NONE);
		btnNewButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				if(threadController == null) {
					threadController = new AppWinThreadController();
					threadControllerThread = new Thread(threadController);		// låt trådkontrollern bli en tråd
					try {
						threadControllerThread.start();							// starta upp Seriekommunikationen
					}
					catch(IllegalThreadStateException itse) {
						System.out.println("IllegalThreadStateException");
					}
				}				 
			}});
		btnNewButton.setBounds(10, 32, 75, 25);
		btnNewButton.setText("START");

		//----------------------------------------------------------------EXIT
		Button btnNewButton_1 = new Button(shell, SWT.NONE);
		btnNewButton_1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (threadControllerThread != null) {
					appwinSerial.setStopSignal();
					try {											
						threadControllerThread.interrupt();			
					}
					catch(SecurityException se) {
						se.printStackTrace();
					}				
					shell.close();
					display.close();
					try {
						this.finalize();
					} catch (Throwable e1) {
						e1.printStackTrace();
					}
				}
				System.out.println("Exit!");
				System.exit(0);				
			}
		});
		btnNewButton_1.setBounds(10, 82, 75, 25);
		btnNewButton_1.setText("EXIT");

		//----------------------------------------------------------------Switcha LED
		Button btnSwitchaLed = new Button(shell, SWT.NONE);
		btnSwitchaLed.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {				
				if (threadControllerThread != null) {
					appwinSerial.toggleSignal();					// toggla styrvillkoret för LED
					try {											
						threadControllerThread.interrupt();			
					}
					catch(SecurityException se) {
						se.printStackTrace();
					}
				}
			}
		});
		btnSwitchaLed.setBounds(103, 32, 75, 25);
		btnSwitchaLed.setText("Switcha LED");

		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
}

Kod: Markera allt

import java.io.DataOutputStream;
import java.io.IOException;
import com.fazecast.jSerialComm.SerialPort;

/*
 * Klassen representerar en seriell com-port där Arduino finns ansluten. 
 */
public class AppWinSerial implements Runnable{
	private int baudRate;								// serieportens i GUI valda överföringshastighet
	private SerialPort serialPort = null; 				
	private DataOutputStream javaToArduinoOut = null;
	private boolean stopSignal;	
	private boolean toggle;

	/*
	 * Konstruktor till objekt av typen AppWinSerial
	 */
	public AppWinSerial() {
		this.stopSignal = false;
		this.toggle = false;
	}

	public void run() {
		try {
			startSerial();
		} catch (InterruptedException e) {
			System.out.println("InterruptedException in Serial run()");
		}
	}
	/*
	 * Skiftar flaggan som använd för att avgöra
	 * om LED ska tändas eller släckas
	 */
	public void toggleSignal() {
		if(this.toggle)
			this.toggle = false;
		else
			this.toggle = true;
	}
	
	public boolean getToggleSignal() {
		return this.toggle;
	}
	/*
	 * Om denna flagga sätts true så indikeras att
	 * kommunikationen med Arduino ska avslutas
	 */
	public void setStopSignal() {
		this.stopSignal = true;
	}
	
	public boolean getStopSignal() {
		return this.stopSignal;
	}
	/*
	 * Baudrate Default är 9600bps
	 * Metoden sätter värdet
	 */
	public void setBaudRate(int baudrate) {
		baudRate = baudrate;
	}
	/*
	 * Returnerar aktuellt satt baudrate
	 */
	public int getBaudRate() {
		return baudRate;
	}
	/*
	 * Påbörjar en kontakt med den COM-port som Arduino är ansluten till och
	 * Denna metod anropas vid tryck på knappen START i GUI.
	 */
	private void startSerial() throws InterruptedException {
		boolean flag = this.comPortSetUp();				// konfigurerar porten
		if(flag) {
			this.LEDcontroller();
		}			
	}
	/*
	 * Metod. Scannar av vilka COM-portar som finns tillgängliga och om Arduino är ansluten
	 * till någon av dessa. Port med Arduino öppnas och porten konfigureras.
	 */
	public boolean comPortSetUp() throws InterruptedException {
		boolean ArduinoUnoFlag = false;
		int ArduinoUnoIndex = -1;	
		SerialPort[] sp = SerialPort.getCommPorts();		
		System.out.println("Antal tillgängliga seriella portar: "+sp.length);				
		for(int j=0;j<sp.length;j++) {
			System.out.println(sp[j].getDescriptivePortName()+" öppen = "+sp[j].isOpen());
			if(sp[j].getDescriptivePortName().contains("Arduino Uno")){
				ArduinoUnoFlag = true;
				ArduinoUnoIndex = j;
			}
		}
		if(ArduinoUnoFlag) {
			serialPort = sp[ArduinoUnoIndex];	
			if(serialPort.isOpen()) {
				serialPort.closePort(); 							// Close connection
			}
			if(!serialPort.isOpen()) {
				serialPort.openPort(); 								// Open connection
			}			
			Thread.sleep(500);
			serialPort.clearDTR();									// Arduino Reset			
			serialPort.setBaudRate(this.getBaudRate());
			serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2500, 0);

			System.out.println(serialPort.getDescriptivePortName()+ " öppnad = "+serialPort.isOpen());			
		}		
		return ArduinoUnoFlag;
	}

	/*
	 *
	 */
	public void LEDcontroller() {	
		try
		{	
			javaToArduinoOut = new DataOutputStream(serialPort.getOutputStream());				
		}
		catch(IllegalStateException  e)
		{
			e.printStackTrace();
		}
		while(true)
		{
			if(Thread.interrupted()) {					
				if(this.stopSignal) {							// denna tråd har blivit avbruten
					break;										// för att avsluta
				}
				try {															
					if(this.toggle) {							// för att toggla LED
						System.out.println("SLÄCK");
						javaToArduinoOut.writeBoolean(false);
					}
					else {
						System.out.println("TÄND");
						javaToArduinoOut.writeBoolean(true);
					}
				}													  
				catch(IOException e) {	
					e.printStackTrace();
				}
			}
		}														// end while			
		if(serialPort.isOpen()) {
			serialPort.closePort();								// koppla ned com-porten
		}
		try {
			javaToArduinoOut.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Kod: Markera allt


public class AppWinThreadController implements Runnable {
	private Thread	arduinoSerialThread;
	private static final int   TIMER_INTERVAL = 500;
	private AppWinSerial appwinSerial;
	
	public AppWinThreadController() {

	}
	public void run() {
		appwinSerial = AppWin.getAppWinSerial();
		arduinoSerialThread = new Thread(appwinSerial);		// låt appwinSerial bli en tråd
		Thread.currentThread().setName("ControllerThread");
		arduinoSerialThread.start();							
		while(true) {
			try {
				Thread.sleep(TIMER_INTERVAL);
			}
			catch(InterruptedException ie) {				
				arduinoSerialThread.interrupt();
			}
			if(Thread.interrupted() && appwinSerial.getStopSignal()) {
				arduinoSerialThread.interrupt();
				break;
			}
		}
	}
}

Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
kodar-holger
EF Sponsor
Inlägg: 747
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: Mätapplikation med Arduino och Java

Inlägg av kodar-holger »

Kod: Markera allt

    if (Serial.read()) { 
Men Serial.read returnerar väl en char och då är den där ju true för nästan allt. Eller?
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Bra fråga, jag blev tvungen att testa.

Fungerar ej
javaToArduinoOut.writeDouble(47);

Fungerar dåligt
javaToArduinoOut.writeInt(-15);


Det jag skickar till Arduinon är en boolean och jag skickar ju inget annat så det fungerar ändå.
Men helt klart så får jag ta och filtrera lite bättre i Arduinokoden.

Kod: Markera allt

	try {															
					if(this.toggle) {							// för att toggla LED
						System.out.println("SLÄCK");
						javaToArduinoOut.writeBoolean(false);
					}
					else {
						System.out.println("TÄND");
						//javaToArduinoOut.writeBoolean(true);
						javaToArduinoOut.writeInt(-15);
					}
				}													  
				catch(IOException e) {	
					e.printStackTrace();
				}
			}

Du kanske har förslag på hur villkoret ska se ut i iffen?
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

Bytte mot det här och det känns ju bättre faktiskt.

Kod: Markera allt

try {															
					if(this.toggle) {							// för att toggla LED
						System.out.println("SLÄCK");
						javaToArduinoOut.writeByte(0);
					}
					else {
						System.out.println("TÄND");
						javaToArduinoOut.writeByte(1);
					}
				}													  
				catch(IOException e) {	
					e.printStackTrace();
				}
och

Kod: Markera allt

// the setup function runs once when you press reset or power the board
int data;
void setup() {
  pinMode(LED_BUILTIN, OUTPUT); 
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.begin(19200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB
  }  
}
void loop() {
  if (Serial.available() > 0) {
    data = Serial.read();
    if (data == 1) {                               // om en boolean true skickats så LED = High
      digitalWrite(LED_BUILTIN, HIGH);
    }
    else {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
}
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

MAX31856_Sch_000.png
Maxim har några ganska lika IC för termoelement, MAX31855, MAX31856, MAX31865
Jag caddade ett kort till en MAX31856 https://www.maximintegrated.com/en/prod ... 31856.html
Lite nytt att ge sig på ytmonterat men det verkar inte finnas något val när det gäller den IC:n.
Cadda går väl an men att montera blir nog inte lätt för en ovan.
Kapseln är en 14-Pin TSSOP. Syns ju knappt!

MAX31856 har olika tabeller för att korrigera kurvor för en mängd element,
A lookup table (LUT) stores linearity correction data for several types of thermocouples (K, J, N, R, S, T, E, and B).
plus en del andra finesser. Kommunikationen sker över SPI.
MAX31856_PCB_000.png
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 12201
Blev medlem: 16 augusti 2009, 19:04:48

Re: Mätapplikation med Arduino och Java

Inlägg av 4kTRB »

MAX31865 är gjord för RTD, alltså den ger ingen spänning ut som ett termoelement
utan det är resistansen som varierar. De har blivit väldigt poppis upp till 600 grader
läste jag. Så jag funderade på om inte det vore fint med ett sånt kort också.
4-trådsmätning stöder chippet. Lite fler pinnar och annan kapsel.

Det blev en del mixter i CAD-programmet men efter att ha studerat databladet och ritningar
på kapseln så hamnade jag nog ganska nära.

TQFN20 heter kapseln och är 5x5mm. Jag är inte helt säker på hur FORCE2-pinnen ska anslutas
men antar att det är till skärmstrumpan?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Senast redigerad av 4kTRB 1 februari 2019, 19:35:14, redigerad totalt 1 gång.
Skriv svar