Re: Mätapplikation med Arduino och Java
Postat: 1 februari 2019, 19:11:39
En pdf om RTD:er https://www.omega.com/temperature/pdf/r ... cs_ref.pdf
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Kod: Markera allt
#include <Arduino.h>
#include "Timer/Timer.h"
Timer t1;
Timer t2;
int tickEvent;
int LEDEvent;
int LEDEvent2;
void doSomething(void* context);
char w[] = {'A','B','C','D','E'};
void* ch = w;
int index = 0;
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
tickEvent = t1.every(1000, doSomething, ch);
LEDEvent = t1.oscillate(13, 75, HIGH);
LEDEvent2 = t2.oscillate(13, 150, HIGH);
}
void loop() {
while(index <=40){
t1.update();
if(index == 15){
t1.stop(LEDEvent);
}
if(index >= 15){
t2.update();
}
}
t1.stop(tickEvent);
t1.stop(LEDEvent);
t2.stop(LEDEvent2);
digitalWrite(13,LOW);
Serial.end();
}
void doSomething(void* ch)
{
char* p = (ch + index % 4);
Serial.write(*p);
Serial.print(" Index = ");
Serial.print(index);
Serial.print(" millisekunder = ");
Serial.println(millis());
index++;
}
Kod: Markera allt
#include <Arduino.h>
//Koden efterliknar en datainsamling av temperatur och NTC-motstånd
//Javaprogrammet har testats och utvecklats mot denna programkörning
// ****************************************************
// variabler och konstanter för kalibrering av brygga
// ****************************************************
bool alertFlag;
int analogPinA = A0; // bryggans anslutning A
int analogPinB = A1; // bryggans anslutning B
int ohm = 500;
const int NUMBER_OF_SAMPLES = 100; // medelvärdesbilda AD-omvandla många gånger
const double DIFF_MAX = 0.01; // tolerans 10 mV för att anse att bryggan är i balans
const double BIT_VOLTAGE_FACTOR = 0.004888; // volt per bit för ad-omvandlare (5.0/1023)
void zeroAdjustAlert(double);
void averageData(double&, double&, double&);
void bridgeZeroAdjust(void);
// ****************************************************
// 0 är startsignal för datainsamling i Arduinos meny
// 1 är startsignal för nollkalibrering av brygga i Arduinos meny
// 2 är startsignal för datainsamling i Arduinos meny
// 3 är startsignal för datainsamling i Arduinos meny
// 4 är Exit i Arduinos meny Serial().end;
// 100 abryter while-loop i ntcMeasurement()
// 200 abryter while-loop i bridgeZeroAdjust()
// Z indikerar att bryggan är i balans i zeroAdjustAlert-funktionen
// X indikerar att bryggan är i obalans i zeroAdjustAlert-funktionen
// the setup function runs once when you press reset or power the board
int celcius;
int inByte = -1; // incoming serial byte
void ntcMeasurement();
void bridgeZeroAdjust();
void setCelcius(int);
int getCelcius();
void setup() {
Serial.begin(19200);
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
}
}
// 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 0: // en NTC-mätning är begärd
ntcMeasurement(); // funktion med while-loop, tar en stund
digitalWrite(LED_BUILTIN, LOW); // visuell indikering på att NTC-mätning är utförd
break; // först nu kan nya menyval utvärderas
case 1:
bridgeZeroAdjust(); // en loop som hela tiden indikerar om bryggan är nolltrimmad eller ej
digitalWrite(13, LOW);
break; // fortsätt i meny-loop när bridgeZeroAdjust() har avslutats
case 2:
break;
case 3:
break;
case 4:
digitalWrite(LED_BUILTIN, HIGH);
delay(3000);
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 i menyloopen
delay(100);
digitalWrite(LED_BUILTIN, LOW);
}
/*
* En loop som mäter obalansen i NTC-mätbryggan.
* 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
* signal till Java-datorn som i sin tur indikerar balans eller obalans i GUI.
* Loopen avbryts manuellt från GUI med tryck på en knapp.
*/
void bridgeZeroAdjust(){
alertFlag = true;
bool breakFlag = true;
double averageVoltA = 0.0;
double averageVoltB = 0.0;
double vDiff = 0.0;
while(breakFlag){
averageData(averageVoltA, averageVoltB, vDiff); // mät obalansen medeelvärdesbilda en aning
zeroAdjustAlert(vDiff); // indikera om en nolljustering utförts
delay(50); // dra ned tempot
if (Serial.available() > 0){ // kommando sänt? Avbryt balanstrimmning av brygga?
if(Serial.read() == 200){ // 200 avbryter while-loop
breakFlag = false;
}
}
}
}
/*
* Argumenten voltA, voltB och voltDiff är call by reference
*/
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)* BIT_VOLTAGE_FACTOR);
sumB += (analogRead(analogPinB)* BIT_VOLTAGE_FACTOR);
}
voltA = sumA/NUMBER_OF_SAMPLES;
voltB = sumB/NUMBER_OF_SAMPLES;
voltDiff = voltA-voltB;
}
/*
* Om bryggan är i balans inom given tolerans så skicka info till Java-datorn
* att balansvillkor är uppfyllt. I GUI indikeras att bryggan är balanstrimmad.
*/
void zeroAdjustAlert(double voltageDiff){
if(fabs(voltageDiff) <= DIFF_MAX){ // om spänningar är lika inom tolerans så
digitalWrite(13, HIGH); // ALERT!
Serial.write("Z"); // Meddela Java-datorn att bryggan är i balans
Serial.write('\n');
}
else{
digitalWrite(13, LOW); // annars så håll lysdioden släckt
Serial.write("X"); // Meddela Java-datorn att bryggan är i obalans
Serial.write('\n');
}
}
void ntcMeasurement(){
setCelcius(24);
int temp = getCelcius();
digitalWrite(LED_BUILTIN, HIGH); // visuell indikering
Serial.write("START");
Serial.write("\n");
while (getCelcius() < 101) {
Serial.print(getCelcius());
Serial.write(" ");
Serial.print(ohm);
Serial.write('\n');
delay(800);
setCelcius(temp++);
ohm = -5.9 * getCelcius() + 635;
if (Serial.available() > 0){ // kommando sänt?
if(Serial.read() == 100){ // 100 avbryter while-loop
setCelcius(101);
}
}
}
}
void setCelcius(int temp){
celcius = temp;
}
int getCelcius(){
return celcius;
}
Kod: Markera allt
START_A = new Button(composite_3, SWT.CENTER);
START_A.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
START_A.setFont(SWTResourceManager.getFont("Segoe UI", 9, SWT.BOLD));
START_A.addMouseListener(new ButtonMouseListener().new START_A_Listener());
START_A.setBounds(199, 0, 52, 45);
START_A.setText("START");
Kod: Markera allt
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.wb.swt.SWTResourceManager;
/*
* Samtliga knappar i GUI reagerar på ett MouseUpEvent i händelsehanteraren.
* Kapparna identifieras i metoden mouseUp nedan och respektive knapps kod exekveras.
*/
public class ButtonMouseListener extends MouseAdapter {
private TextFile textFile;
public ButtonMouseListener() {
this.textFile = NTC.getTextFile();
}
/*
*
*/
public class START_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
if(NTC.getArduinoConnectedFlag()) { // se till att Arduino finns uppkopplad
NTC.resetTimer();
textFile.setTextFileName(NTC.txtDatatxt.getText()); // hämta text från textfält med önskat filnamn
NTC.resetLedDisplay();
NTC.buttonStart.setEnabled(false);
if(NTC.threadControllerThread[4].isAlive()) {
NTC.threadControllerThread[4] = new Thread (NTC.threadController[4]);
}
try {
NTC.threadControllerThread[4].start(); // starta trådkontrollern
System.out.println(NTC.threadControllerThread[4].getName() + " är startad");
}
catch(IllegalThreadStateException itse) {
System.out.println("IllegalThreadStateException");
}
}
}
}
/*
*
*/
public class STOPP_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
if (NTC.threadControllerThread[4].isAlive()) { // signalera Stopp till Arduino-inläsningen
try { // avbryt trådkontrollern som i sin tur avbryter
NTC.threadControllerThread[4].interrupt(); // inäsning av data från Arduinon
System.out.println(NTC.threadControllerThread[4].getName() + " är avbruten");
}
catch(SecurityException se) {
System.out.println("SecurityException");
}
}
}
}
/*
*
*/
public class EXIT_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
System.out.println("EXIT-EXIT-EXIT-EXIT-EXIT");
if(NTC.getArduinoConnectedFlag()) {
(new Thread () { // en tråd skriver ett EXIT-kommando till Arduino
DataOutputStream javaToArduinoOut = null;
public void run() {
javaToArduinoOut = new DataOutputStream(Test.getSerialPort().getOutputStream());
try {
javaToArduinoOut.writeByte(NTC.EXITZEROADJUST); // avbryt eventuell nolltrim-loop
javaToArduinoOut.writeByte(NTC.EXITNTCMEASURE); // avbryt eventuell ntc-mät-loop
javaToArduinoOut.writeByte(NTC.EXIT); // menyval för Exit i Arduinos meny
} catch (IOException e1) {
e1.printStackTrace();
}
try {
javaToArduinoOut.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
NTC.threadControllerThread[0].interrupt();
NTC.threadControllerThread[1].interrupt();
NTC.threadControllerThread[2].interrupt();
NTC.threadControllerThread[3].interrupt();
NTC.threadControllerThread[4].interrupt();
NTC.threadControllerThread[5].interrupt();
}
catch (SecurityException se){
System.out.println("SecurityException");
}
}
}).start();
}
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("EXIT");
NTC.shlNtc.close();
// display.close();
SWTResourceManager.dispose();
System.exit(0);
}
}
/*
*
*/
public class OK_ABC_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
NTC.threadControllerThread[1].interrupt(); // avbryt samtliga kalibreringstrådar
NTC.threadControllerThread[2].interrupt();
NTC.threadControllerThread[3].interrupt();
NTC.threadControllerThread[5].interrupt();
if(NTC.getArduinoConnectedFlag()) { // se till att Arduino finns uppkopplad
NTC.threadStack.clearStack(); // lägg upp ordning för kalibreringsprocedur
NTC.threadStack.push("F"); // RrefB trim klart/OK
NTC.threadStack.push("E"); // trimma med RrefB
NTC.threadStack.push("D"); // RrefA trim klart/OK
NTC.threadStack.push("C"); // trimma med RrefA
NTC.threadStack.push("B"); // nolltrim klart/OK
NTC.threadStack.push("A"); // start nolltrim
}
NTC.OK_ABC.setForeground(SWTResourceManager.getColor(255, 255, 204));
NTC.OK_ABC.setBackground(SWTResourceManager.getColor(204, 51, 51));
System.out.println("NTC.OK_ABC");
}
}
/*
*
*/
public class START_A_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent arg0) {}
public void mouseDown(MouseEvent arg0) {}
public void mouseUp(MouseEvent e) {
if(NTC.getArduinoConnectedFlag()) { // se till att Arduino finns uppkopplad
if(NTC.threadStack.lookAtTheTopOfStack() == "A") {
NTC.progressBarA.setSelection(0);
NTC.progressBarB.setSelection(0);
NTC.threadStack.pop();
if(NTC.threadControllerThread[1].isAlive())
NTC.threadControllerThread[1].interrupt();
NTC.threadControllerThread[5].interrupt();
NTC.threadControllerThread[1] = new Thread (NTC.threadController[1]);
NTC.threadControllerThread[5] = new Thread (NTC.threadController[5]);
try {
NTC.threadControllerThread[1].start(); // starta trådkontrollern
NTC.threadControllerThread[5].start();
NTC.OK_ABC.setForeground(SWTResourceManager.getColor(0, 0, 0));
NTC.OK_ABC.setBackground(SWTResourceManager.getColor(250, 250, 250));
}
catch(IllegalThreadStateException itse) {
System.out.println("IllegalThreadStateException");
}
}
}
System.out.println("NTC.START_A");
}
}
/*
*
*/
public class OK_A_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
if(NTC.threadStack.lookAtTheTopOfStack() == "B") {
NTC.threadStack.pop();
try { // avbryt trådkontrollern
NTC.threadControllerThread[1].interrupt();
NTC.threadControllerThread[5].interrupt();
}
catch(SecurityException se) {
System.out.println("SecurityException");
}
NTC.progressBarA.setSelection(0);
NTC.progressBarB.setSelection(0);
}
System.out.println("NTC.OK_A");
}
}
/*
*
*/
public class START_B_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
if(NTC.getArduinoConnectedFlag()) { // se till att Arduino finns uppkopplad
if(NTC.threadStack.lookAtTheTopOfStack() == "C") {
NTC.threadStack.pop();
if(NTC.threadControllerThread[2].isAlive())
NTC.threadControllerThread[2].interrupt();
NTC.threadControllerThread[2] = new Thread (NTC.threadController[2]);
try { // och att trådstart sker i rätt ordning
NTC.threadControllerThread[2].start(); // innan trådkontrollern startas
}
catch(IllegalThreadStateException itse) {
System.out.println("IllegalThreadStateException");
}
}
}
System.out.println("NTC.START_B");
}
}
/*
*
*/
public class OK_B_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
if(NTC.threadStack.lookAtTheTopOfStack() == "D"){
NTC.threadStack.pop();
try { // avbryt trådkontrollern
NTC.threadControllerThread[2].interrupt();
}
catch(SecurityException se) {
System.out.println("SecurityException");
}
}
System.out.println("NTC.OK_B");
}
}
/*
*
*/
public class START_C_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
if(NTC.getArduinoConnectedFlag()) { // se till att Arduino finns uppkopplad
if(NTC.threadStack.lookAtTheTopOfStack() == "E") {
NTC.threadStack.pop();
if(NTC.threadControllerThread[3].isAlive())
NTC.threadControllerThread[3].interrupt();
NTC.threadControllerThread[3] = new Thread (NTC.threadController[3]);
try { // och att trådstart sker i rätt ordning
NTC.threadControllerThread[3].start(); // innan trådkontrollern startas
}
catch(IllegalThreadStateException itse) {
System.out.println("IllegalThreadStateException");
}
}
}
System.out.println("NTC.START_C");
}
}
/*
*
*/
public class OK_C_Listener implements MouseListener{
public void mouseDoubleClick(MouseEvent e) {}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {
if(NTC.threadStack.lookAtTheTopOfStack() == "F") {
NTC.threadStack.pop();
try { // avbryt trådkontrollern
NTC.threadControllerThread[3].interrupt();
}
catch(SecurityException se) {
System.out.println("SecurityException");
}
}
System.out.println("NTC.OK_C");
}
}
}
Kod: Markera allt
private Object tc0 = null; // objekt som ska köras av trådkontrollern
private Object tc1 = null; // objekten implementerar interfacet Runnable
private Object tc2 = null;
private Object tc3 = null;
private Object tc4 = null;
private Object tc5 = null;
public static ThreadController[] threadController; // varje tråd har en trådkontroller
public static Thread[] threadControllerThread; // varje trådkontroller körs som en tråd
Kod: Markera allt
/*
* Skapar det antal trådkontrollörer som behövs och förbereder dem för start.
* Till varje trådkontrollör kopplas ett objekt som trådkontrollören sedan ska starta
* i sin run-metod. Klasserna/objekten som ska köras som tråd implementerar interfacet Runnable.
* Även trådkontrollern implementerar interfacet Runnable då den också körs som tråd.
* För att stoppa en tråd skickas ett interrupt till trådkotrollern som då kastar ett
* InterruptedException vari i sin tur ett interrupt utförs på tråden som trådkontrollören
* tidigare startat. Tråden avslutas och även trådkontrollören(dess tråd). Trådkontrollören kan
* inte startas på nytt utan då måste en ny trådkontrollör skapas om en objekt-tråd ska startas och köras på nytt.
*/
private void setUpThreadControllers() {
tc0 = new Test(window,display); // skapa de objekt som ska köras som tråd
Test.setBaudRate(NTC.DEFAULTBAUDRATE); // tc0 Anslut Arduino via comport
tc1 = new Test_1(display); // tc1 Nolltrimma NTC-brygga
tc2 = new Test_2(); // tc2 Ta fram ekvation R som funktion av bryggspänning RrefA
tc3 = new Test_3(); // tc3 Ta fram ekvation R som funktion av bryggspänning RrefB
tc4 = new CollectArduinoData(window,display); // tc4 NTC-mätning
CollectArduinoData.setBreakTemp(NTC.DEFAULTBREAKTEMP); // default temperatur då mätning ska avbrytas
tc5 = new MinusZeroPlusMeter(display);
threadController = new ThreadController[NTC.NUMBEROFTHREADS];
threadControllerThread = new Thread[NTC.NUMBEROFTHREADS];
threadController[0] = new ThreadController(tc0); // en klass som körs som tråd
threadController[1] = new ThreadController(tc1);
threadController[2] = new ThreadController(tc2);
threadController[3] = new ThreadController(tc3);
threadController[4] = new ThreadController(tc4);
threadController[5] = new ThreadController(tc5);
threadControllerThread[0] = new Thread (threadController[0]); // trådkontrollern threadController körs som tråd
threadControllerThread[1] = new Thread (threadController[1]);
threadControllerThread[2] = new Thread (threadController[2]);
threadControllerThread[3] = new Thread (threadController[3]);
threadControllerThread[4] = new Thread (threadController[4]);
threadControllerThread[5] = new Thread (threadController[5]);
}
Kod: Markera allt
public class ThreadController implements Runnable {
private Object obj;
private Thread objectThread;
private static final int TIMER_INTERVAL = 2000; // The timer interval in milliseconds
/*
* Konstruktor för en trådkontroller som startar
* ett valbart Runnable-objekt/klass i form av en tråd.
* Trådkontrollern ligger periodvis i viloläge tills
* den blir avbruten. Vid avbrott avbryts den startade
* tråden och sedan avslutar trådkontrollern sin while-loop.
* Objekttypen som skickas med, när en instans av trådkontrollern skapas,
* är en klass som implementerar interfacet Runnable och som alltså är avsedd
* att exekveras som en tråd. Varje trådkontroller är bunden till detta objekt.
* Ingen startad trå kan startas på nytt utan då måste en ny trådkontroller
* för Runnable-objektet skapas på nytt.
*/
public ThreadController(Object object) {
this.obj = object;
}
/**
* Startar vald klass som en tråd. Vid interrupt() görs avbrott
* i klassobjekten som därefter avslutar sin aktivitet
* som tråd. while-loopen nedan avslutas och även run().
*/
public void run() {
objectThread = new Thread( (Runnable) obj); // skapar en ny tråd
objectThread.start();
while(true) {
try {
Thread.sleep(TIMER_INTERVAL);
}
catch(InterruptedException ie) {
objectThread.interrupt();
System.out.println("Avbrott i tråden till " + this.obj.toString());
}
}
}
}
Kod: Markera allt
#include <Arduino.h>
//Koden efterliknar en datainsamling av temperatur och NTC-motstånd
//Javaprogrammet har testats och utvecklats mot denna programkörning
// ****************************************************
// variabler och konstanter för kalibrering av brygga
// ****************************************************
bool alertFlag;
int analogPinA = A0; // bryggans anslutning A
int analogPinB = A1; // bryggans anslutning B
int ohm;
const int NUMBER_OF_SAMPLES = 250; // medelvärdesbilda AD-omvandla många gånger
void zeroAdjustAlert(int);
void averageData(int&, int&, int&);
void bridgeZeroAdjust(void);
// ****************************************************
// 0 är startsignal för datainsamling i Arduinos meny
// 1 är startsignal för nollkalibrering av brygga i Arduinos meny
// 2 är startsignal för datainsamling i Arduinos meny
// 3 är startsignal för datainsamling i Arduinos meny
// 4 är Exit i Arduinos meny Serial().end;
// 100 abryter while-loop i ntcMeasurement()
// 200 abryter while-loop i bridgeZeroAdjust()
// Z indikerar att bryggan är i balans i zeroAdjustAlert-funktionen
// X indikerar att bryggan är i obalans i zeroAdjustAlert-funktionen
// the setup function runs once when you press reset or power the board
int celcius;
int inByte = -1; // incoming serial byte
void ntcMeasurement();
void bridgeZeroAdjust();
void setCelcius(int);
int getCelcius();
void setup() {
Serial.begin(19200);
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
}
}
// 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 0: // en NTC-mätning är begärd
ntcMeasurement(); // funktion med while-loop, tar en stund
digitalWrite(LED_BUILTIN, LOW); // visuell indikering på att NTC-mätning är utförd
break; // först nu kan nya menyval utvärderas
case 1:
bridgeZeroAdjust(); // en loop som hela tiden indikerar om bryggan är nolltrimmad eller ej
break; // fortsätt i meny-loop när bridgeZeroAdjust() har avslutats
case 2:
break;
case 3:
break;
case 4:
digitalWrite(LED_BUILTIN, HIGH);
delay(3000);
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 i menyloopen
delay(100);
digitalWrite(LED_BUILTIN, LOW);
}
/*
* En loop som mäter obalansen i NTC-mätbryggan.
* 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
* signal till Java-datorn som i sin tur indikerar balans eller obalans i GUI.
* Loopen avbryts manuellt från GUI med tryck på en knapp.
*/
void bridgeZeroAdjust(){
alertFlag = true;
bool breakFlag = true;
int averageVoltA;
int averageVoltB;
int vDiff;
Serial.write("ZERO");
Serial.write("\n");
while(breakFlag){
averageVoltA = 0;
averageVoltB = 0;
vDiff = 0;
averageData(averageVoltA, averageVoltB, vDiff); // mät obalansen medeelvärdesbilda en aning
zeroAdjustAlert(vDiff); // indikera om en nolljustering utförts
delay(100);
if (Serial.available() > 0){ // kommando sänt? Avbryt balanstrimmning av brygga?
if(Serial.read() == 200){ // 200 avbryter while-loop
breakFlag = false;
}
}
}
}
/*
* Argumenten voltA, voltB och voltDiff är call by reference
* Upplösningen är 5/1023 = 4.8888 mV per bit
* Beräkning av spänning sker hos Java-datorn
*/
void averageData(int& voltA, int& voltB, int& voltDiff){
int sumA = 0;
int sumB = 0;
for(int i = 0; i < NUMBER_OF_SAMPLES; i++){
sumA += analogRead(analogPinA);
sumB += analogRead(analogPinB);
}
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 zeroAdjustAlert(int voltageDiff){
Serial.println(voltageDiff);
}
void ntcMeasurement(){
ohm = 500;
setCelcius(24);
int temp = getCelcius();
digitalWrite(LED_BUILTIN, HIGH); // visuell indikering
Serial.write("START");
Serial.write("\n");
while (getCelcius() < 101) {
Serial.print(getCelcius());
Serial.write(" ");
Serial.print(ohm);
Serial.write('\n');
delay(800);
setCelcius(++temp);
ohm = -5.9 * getCelcius() + 635;
if (Serial.available() > 0){ // kommando sänt?
if(Serial.read() == 100){ // 100 avbryter while-loop
setCelcius(101);
}
}
}
}
void setCelcius(int temp){
celcius = temp;
}
int getCelcius(){
return celcius;
}
Kod: Markera allt
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Scanner;
import org.eclipse.swt.widgets.Display;
public class Test_1 implements Runnable {
private DataOutputStream javaToArduinoOut = null; //write primitive Java datatypes to an output stream
private Scanner arduinoScanIn = null; // produces values scanned from the specified input stream
private String data = null;
private Display display = null;
private MinusZeroPlusMeter minusZeroPlusMeter = null;
private double vMilliVolt;
public Test_1(Display display, MinusZeroPlusMeter minusZeroPlusMeter) {
this.display = display;
this.minusZeroPlusMeter = minusZeroPlusMeter;
}
@Override
public void run() {
ntcBridgeZeroAdjust();
}
/*
*
*/
private void ntcBridgeZeroAdjust() {
javaToArduinoOut = new DataOutputStream(Test.getSerialPort().getOutputStream());
arduinoScanIn = new Scanner(Test.getSerialPort().getInputStream());
try {
javaToArduinoOut.writeByte(NTC.STARTZEROADJUST); // startsignal för nolltrimma brygga i Arduinos meny
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(arduinoScanIn.findInLine("ZERO")); // Efter texten ZERO skickas ADC-data
arduinoScanIn.nextLine();
while(true) { // stanna kvar i nolltrim-läge tills avbrott kommer
try {
Thread.sleep(20); // måste anpassas till delay i loopen till bridgeZeroAdjust() i Arduinokoden
} catch (InterruptedException e) { // fånga ett trådavbrott
try {
javaToArduinoOut.writeByte(200); // 200 är avsluta-signal för Arduinos nolltrim-funktion
while(arduinoScanIn.hasNextLine()) { // om arduino skickar extra
arduinoScanIn.nextLine(); // strängar så ta inte med dessa
}
break;
} catch (IOException e1) {
e1.printStackTrace();
}
}
data = arduinoScanIn.nextLine(); // läs in data som zeroAdjustAlert-funktionen hos
vMilliVolt = (double) Math.round(4.8888 * Double.parseDouble(data));
// 0 + 244 = 244 , 50*4.8888 + 244 = 488, -50*4.8888 + 244 = 0
// progress bars är 488 steg långa vilket ger indikation mellan +/-50 mV
display.asyncExec (new Runnable () {
public void run () {
NTC.setVdiffLabelText(vMilliVolt + " mV");
minusZeroPlusMeter.setSelectionValue((int) Math.round(vMilliVolt*4.889+244));
}
});
}
arduinoScanIn.close(); // avsluta skannern
try {
javaToArduinoOut.close(); //avsluta data output stream
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("End from ntcBridgeZeroAdjust " + this.toString() + "!");
}
public String toString() {
return "Test 1";
}
}
Kod: Markera allt
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ProgressBar;
public class MinusZeroPlusMeter implements Runnable {
private final int PROGRESSBARMAXIMUM = 488;
private ProgressBar pgA;
private ProgressBar pgB;
private Display display = null;
private int selection;
public MinusZeroPlusMeter(Display display) {
this.display = display;
pgA = NTC.getProgressBarA();
pgB = NTC.getProgressBarB();
pgA.setMaximum(PROGRESSBARMAXIMUM);
pgB.setMaximum(PROGRESSBARMAXIMUM);
pgA.setSelection(0);
pgB.setSelection(0);
this.selection = 0;
this.setSelectionValue(244);
}
@Override
public void run() {
work();
display.asyncExec (new Runnable () {
public void run () {
pgA.setSelection(getSelectionValue());
pgB.setSelection(PROGRESSBARMAXIMUM-getSelectionValue());
}
});
}
private void work() {
while(true) {
display.asyncExec (new Runnable () {
public void run () {
pgA.setSelection(getSelectionValue());
pgB.setSelection(PROGRESSBARMAXIMUM-getSelectionValue());
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
System.out.println("End from Utskrift "+ this.toString() + "!");
}
public void setSelectionValue(int v) {
this.selection = v;
}
private int getSelectionValue() {
return this.selection;
}
public String toString() {
return "MinusZeroPlusMeter";
}
}
Kod: Markera allt
#include <Arduino.h>
//Koden efterliknar en datainsamling av temperatur och NTC-motstånd
//Javaprogrammet har testats och utvecklats mot denna programkörning
// ****************************************************
// 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;
typedef char* CharPointer;
CharPointer Ra = "RA"; // samma funktion används för att kalibrera med
CharPointer Rb = "RB"; // RA och RB, bara olika id-för java-datorn
// ****************************************************
// 0 är startsignal för datainsamling i Arduinos meny
// 1 är startsignal för nollkalibrering av brygga i Arduinos meny
// 2 är startsignal för datainsamling i Arduinos meny
// 3 är startsignal för datainsamling i Arduinos meny
// 4 är Exit i Arduinos meny Serial().end;
// WHILE_LOOP_BREAK abryter while-loop i respektive mätloop
const int COLLECT_DATA = 0;
const int ZERO_ADJUST = 1;
const int CALIBRATE_RA = 2;
const int CALIBRATE_RB = 3;
const int EXIT = 4;
const int WHILE_LOOP_BREAK = 255;
// Funktionsdeklarationer
// ****************************************************
void rRefAdjust(CharPointer);
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
}
}
// 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 ZERO_ADJUST:
digitalWrite(LED_BUILTIN, HIGH);
bridgeZeroAdjust(); // en loop som hela tiden indikerar om bryggan är nolltrimmad eller ej
break; // fortsätt i meny-loop när bridgeZeroAdjust() har avslutats
case CALIBRATE_RA:
digitalWrite(LED_BUILTIN, HIGH);
rRefAdjust(Ra); // en loop som hela tiden indikerar spänningen från bryggan
break; // med kalibreringsmotståndet Ra anslutet
case CALIBRATE_RB:
digitalWrite(LED_BUILTIN, HIGH);
rRefAdjust(Rb);
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 och RB.
* Loopen avbryts manuellt från GUI med tryck på en knapp.
*/
void rRefAdjust(CharPointer 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 eller RB innan data börjar
averageVoltA = 0; // samlas in
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){ // 200 avbryter while-loop
breakFlag = false;
}
}
}
}
/*
* 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));
}
void ntcMeasurement(){
int ohm = 500;
setCelcius(24);
int temp = getCelcius();
Serial.write("START");
Serial.write("\n");
while (getCelcius() < 101) {
Serial.print(getCelcius());
Serial.write(" ");
Serial.print(ohm);
Serial.write("\n");
delay(800);
setCelcius(++temp);
ohm = -5.9 * getCelcius() + 635;
if (Serial.available() > 0){ // kommando sänt?
if(Serial.read() == WHILE_LOOP_BREAK){ // avbryter while-loop
setCelcius(101);
}
}
}
}
/*
* 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 celcius;
}
Kod: Markera allt
import java.io.IOException;
import java.util.NoSuchElementException;
public class Test_2 implements Runnable {
private String data;
private int vMilliVolt;
private int value;
public Test_2() {
}
@Override
public void run() {
NTC.getThreadControllerThread()[5] = new Thread (NTC.getThredController()[5]);
try {
NTC.getThreadControllerThread()[5].start(); // MinusZeroPlusMeter
} catch (IllegalThreadStateException itse) {
System.out.println("IllegalThreadStateException");
}
ntcBridgeAdjustRA();
try {
NTC.getThreadControllerThread()[5].interrupt();
} catch (SecurityException e) {
e.printStackTrace();
}
System.out.println("End from " + this.toString() + "!");
}
private void ntcBridgeAdjustRA() {
try {
NTC.getJavaToArduinoOut().writeByte(NTC.STARTREFA); // startsignal för kalibrera brygga med referens RA
} catch (IOException e1) { // i Arduinos meny
e1.printStackTrace();
}
int i = 0;
try {
data = NTC.getArduinoScanIn().nextLine();
} catch(NoSuchElementException e) { }
while(!data.equals(NTC.ARDUINOCALIBRATE_RA)) { // Efter texten skickas ADC-data
try {
data = NTC.getArduinoScanIn().nextLine();
} catch(NoSuchElementException e) { }
i++;
}
System.out.println("data = " + data + " i = " + i);
while(true) { // stanna kvar i kalibrerings-läge
try {
Thread.sleep(2);
} catch (InterruptedException e) { // fånga ett trådavbrott
try {
NTC.getJavaToArduinoOut().writeByte(NTC.WHILELOOPEXIT); // avsluta-signal för Arduinos mätloop
} catch (IOException e1) {
e1.printStackTrace();
}
break; // hoppa ur while-loop och avsluta
}
try {
data = NTC.getArduinoScanIn().nextLine(); // läs in data motsvarande bryggans
} catch(NoSuchElementException e) { }
try { // obalansspänning för RrefA
value = Integer.parseInt(data); // data är a/d-omvandlarens bitvärde som ett heltal
} catch(java.lang.NumberFormatException nfe) { // levererat som en textsträng
System.out.println("NumberFormatException in Test 2");
}
vMilliVolt = (int) Math.round(4.8828 * value); // 5V/1023 = 4.888 mV/bit
// 0 + 244 = 244 , 50*4.888 + 244 = 488, -50*4.888 + 244 = 0
// progress bars är 488 steg långa vilket ger indikation mellan +/-50 mV
NTC.getDisplay().asyncExec (new Runnable () {
public void run () {
NTC.getLabelVdiff().setText(vMilliVolt + " mV" + " data (0-1023) = " + data);
NTC.getMinusZeroPlusMeter().setSelectionValue((int) Math.round(vMilliVolt*4.8828+244));
}
});
};
}
public String toString() {
return "Kalibrera med RrefA";
}
}
Kod: Markera allt
public class LinearEquation {
private double va;
private double vb;
private double ra;
private double rb;
private double k;
private double m;
public LinearEquation() {
va = vb = ra = rb = k = m = 0;
}
public void setVa(double value) {
this.va = value;
}
public double getVa() {
return this.va;
}
public void setVb(double value) {
this.vb = value;
}
public double getVb() {
return this.vb;
}
public void setRa(int value) {
this.ra = (double) value;
}
public double getRa() {
return this.ra;
}
public void setRb(int value) {
this.rb = (double) value;
}
public double getRb() {
return this.rb;
}
public void calculate_k() {
this.k = (this.vb-this.va)/(this.rb-this.ra);
}
public double get_k() {
return this.k;
}
public void calculate_m() {
this.m = this.vb-this.k*this.rb;
}
public double get_m() {
return this.m;
}
public double calculateNTCresistance(double voltage){
return (voltage - this.m) / this.k;
}
}