Skip to content

Commit 8e33609

Browse files
committed
Added project files for HardwareX special issue
Files for "Special Issue on Open Source Machinery and Laboratory Instrument using the Arduino Software and Hardware Ecosystem" of HardwarX
1 parent aef05d1 commit 8e33609

25 files changed

+1497
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This repositoy contains the source files for the Electric Drive Ardunio Interface that was developed during the Master's Thesis of [@AnnikenKva](https://github.com/AnnikenKva) at the [University of South-Eastern Norway](https://www.usn.no) in Spring 2022.
44

5+
![Image of physical setup](setup.jpg)
6+
57
## Repository description
68

79
The repository is organised in the following way:

arduino/.placeholder

Whitespace-only changes.

arduino/arduinoMain.ino

Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
/* Sketch for ARDUINO communication with Python.
2+
*
3+
* Part of master's thesis spring 2022.
4+
* Anniken Semb Kvalsund
5+
* Electrical Power Engineering.
6+
*
7+
*/
8+
9+
// Constants
10+
const int AI[3] = {A0, A1, A2}; // Creates an array of all the analog inputs
11+
byte noAI = (sizeof(AI)/sizeof(AI[0])); // Finds the number of elements in AI array. To use in for loops etc
12+
13+
// Variables
14+
int data1 = 0; // Input information. Initialise to zero.
15+
int i = 0;
16+
17+
bool readAI = false;
18+
bool writeADO = false;
19+
bool calibrateAO = false;
20+
bool LEDcontr = false;
21+
22+
int AIs[10]; // For "storing" collected analogue input values
23+
char AIstring[16]; // For storing AI values converted to string
24+
25+
// Write data constants and variables
26+
const byte numChars = 16;
27+
char receivedChars[numChars]; // an array to store the received data
28+
byte ndx = 0;
29+
boolean newData = false;
30+
char analogDigital;
31+
int channel; // Converts the number recieved in channel number to an int
32+
int chValConv; // Sends the char chVal to string toInt function, returned scaled and converted to int.
33+
int outVal; // Output value to analogue PWM outputs.
34+
bool LEDon = false; // LED controlling variable.
35+
36+
// Maxvalue to PWM outputs. Adjustable to ensure 5V, not more, is output at max.
37+
int max_out_AO0 = 255;
38+
int max_out_AO1 = 255;
39+
int max_out_AO2 = 255;
40+
int max_out_AO3 = 255;
41+
42+
// Declare outputs
43+
const int DO0 = 2;
44+
const int DO1 = 4;
45+
const int DO2 = 7;
46+
const int DO3 = 8;
47+
48+
const int AO0 = 3; // 0-10V
49+
const int AO1 = 5; // 0-10V
50+
const int AO2 = 6; // +-10V
51+
const int AO3 = 9; // +-10V
52+
53+
54+
void setup() {
55+
// Setting up an initialise the serial communication
56+
Serial.begin(9600);
57+
pinMode(LED_BUILTIN, OUTPUT);
58+
pinMode(DO0, OUTPUT);
59+
pinMode(DO1, OUTPUT);
60+
pinMode(DO2, OUTPUT);
61+
pinMode(DO3, OUTPUT);
62+
pinMode(AO0, OUTPUT);
63+
pinMode(AO1, OUTPUT);
64+
pinMode(AO2, OUTPUT);
65+
pinMode(AO3, OUTPUT);
66+
67+
}
68+
69+
70+
71+
void loop() {
72+
if(Serial.available()>0){ // Return the number of bytes available on serial. if <0, = no info on serial.
73+
74+
recvWithEndMarker();
75+
76+
if(readAI == true){
77+
analoginputs();
78+
readAI = false;
79+
}
80+
81+
if(writeADO == true){
82+
analogueOut();
83+
writeADO = false;
84+
}
85+
86+
if(calibrateAO == true){
87+
calibrateAO_func();
88+
calibrateAO = false;
89+
}
90+
91+
if (LEDcontr == true){
92+
LEDonoff();
93+
LEDcontr = false;
94+
}
95+
96+
else{/* Do nothing*/}
97+
} // if serial available
98+
} // Void loop
99+
100+
//_____________________________________________________________________________________________
101+
// Read analogue inputs
102+
103+
void analoginputs(){
104+
for ( i=0; i<=noAI; i++){
105+
AIs[i] = analogRead(AI[i]);
106+
} // for AI
107+
108+
// Converting the analog input values to a single string with x's separating each value.
109+
sprintf(AIstring, "%dx%dx%d" , AIs[0],AIs[1],AIs[2]);
110+
Serial.println(AIstring); // Writes data from AI to serial bus
111+
} // void analoginputs
112+
113+
114+
//_____________________________________________________________________________________________
115+
// Reads from Serial port until endChar '\n' is received.
116+
117+
void recvWithEndMarker() {
118+
char endMarker = '\n';
119+
char rc;
120+
boolean done = false;
121+
122+
while (Serial.available() && !done) {
123+
rc = Serial.read();
124+
if (rc == endMarker) {
125+
done = true;
126+
newData = true;
127+
}
128+
else {
129+
receivedChars[ndx++] = rc;
130+
if (ndx >= numChars)
131+
done = true;
132+
}
133+
}
134+
135+
if (newData) {
136+
if (!parseInput()) { // if we call parseData it fails there is no need to process that data further.
137+
//Serial.println("String couldn't be parsed");
138+
newData = false;
139+
}
140+
ndx = 0;
141+
}
142+
}
143+
144+
145+
//_____________________________________________________________________________________________
146+
// Splits the received string into its separate characters and stores them in globals
147+
148+
boolean parseInput() {
149+
int secondX = -1;
150+
String tempString;
151+
String chValConvtemp;
152+
char Buf[2]; // For converting string to char
153+
154+
155+
for (int i = 0; i < ndx; i++)
156+
//Serial.print(receivedChars[i]);
157+
//Serial.println();
158+
159+
if (receivedChars[1] != 'x'){ // If no further values are read, ie not split by x'es
160+
if (receivedChars[0] == 'e'){ readAI = true;} // The readAI value is set to true, causing readAI function to run
161+
if (receivedChars[0] == 'h'){ LEDcontr = true; LEDon = true;}
162+
if (receivedChars[0] == 'i'){ LEDcontr = true; LEDon = false;}
163+
return false;}
164+
else { // If more than one value is transmitted
165+
166+
if (receivedChars[0] == 'o' or receivedChars[0] == 'p'){ writeADO = true; analogDigital = receivedChars[0];} // Prepare to write values
167+
if (receivedChars[0] == 'q'){ calibrateAO = true;} // Prepare to calibrate (using the same message system as writeADO
168+
169+
for (int i = 3; i < ndx && secondX == -1; i++)
170+
if (receivedChars[i] == 'x')
171+
secondX = i;
172+
173+
if (secondX == -1)
174+
return false;
175+
176+
tempString = receivedChars;
177+
channel = tempString.substring(2, secondX).toInt();
178+
179+
chValConvtemp = tempString.substring(secondX + 1, ndx);
180+
chValConvtemp.toCharArray(Buf, 2);
181+
chValConv = int(Buf[0]);
182+
183+
// Print for troubleshooting
184+
Serial.print("analogDigital -> ");
185+
Serial.println(analogDigital);
186+
Serial.print("channel -> ");
187+
Serial.println(channel);
188+
Serial.print("chValConv -> ");
189+
Serial.println(chValConv);
190+
}
191+
return true;
192+
}
193+
194+
//_____________________________________________________________________________________________
195+
// Write analogue and / or digital values
196+
197+
void analogueOut() { // Writes to analogue outputs
198+
199+
if (newData == true) {
200+
// Result in an array with two elements. One A1/D2 etc and one Value/onoff
201+
202+
if (analogDigital == 'o') {
203+
//Serial.println("Analogue");
204+
205+
switch (channel) {
206+
case 0:
207+
//Serial.println("AO0");
208+
outVal = constrain((map(chValConv, 0, 100, 0, max_out_AO0)), 0, max_out_AO0);
209+
analogWrite(AO0, outVal);
210+
break;
211+
case 1:
212+
//Serial.println("AO1");
213+
outVal = constrain((map(chValConv, 0, 100, 0, max_out_AO1)), 0, max_out_AO1);
214+
analogWrite(AO1, outVal);
215+
break;
216+
case 2:
217+
//Serial.println("AO2");
218+
outVal = constrain((map(chValConv, 0, 100, 0, max_out_AO2)), 0, max_out_AO2);
219+
analogWrite(AO2, outVal);
220+
break;
221+
case 3:
222+
//Serial.println("AO3");
223+
outVal = constrain((map(chValConv, 0, 100, 0, max_out_AO3)), 0, max_out_AO3);
224+
analogWrite(AO3, outVal);
225+
break;
226+
default:
227+
//Serial.println("NaN");
228+
break;
229+
} // Switch case channel
230+
231+
} // if recievedArray[0]=o
232+
233+
else if (analogDigital == 'p') {
234+
//Serial.println("Digital");
235+
bool dContr = false;
236+
237+
// Creating a "buffer"
238+
if (chValConv < 50){dContr = LOW;}
239+
else if (chValConv >= 50){dContr = HIGH;}
240+
else {dContr = LOW;}
241+
242+
switch (channel) {
243+
case 0:
244+
//Serial.println("DO0");
245+
digitalWrite(DO0, dContr);
246+
break;
247+
case 1:
248+
//Serial.println("DO1");
249+
digitalWrite(DO1, dContr);
250+
break;
251+
case 2:
252+
//Serial.println("DO2");
253+
digitalWrite(DO2, dContr);
254+
break;
255+
case 3:
256+
//Serial.println("DO3");
257+
digitalWrite(DO3, dContr);
258+
break;
259+
default:
260+
//Serial.println("NaN");
261+
break;
262+
} // Switch case channel
263+
264+
} // if recievedArray[0]=p
265+
266+
else {
267+
//Serial.println("Channel not valid");
268+
} // if recievedArray[0]=p
269+
270+
newData = false;
271+
} // if newData True
272+
} // void analogueOut
273+
274+
275+
//_____________________________________________________________________________________________
276+
277+
// Function for converting the recieved value 0-100 to calibration values, or reset cal. vlaues.
278+
int calEq(int range, int measVal, int maxOut){
279+
int maxOut_tmp; // For storing the value temporary
280+
281+
if (measVal == 114){ // If measVal is 114, aka reset, the max \Out is set to default 255
282+
maxOut_tmp = 255;
283+
} // if measVal 114('r')
284+
else { // If measVal is something else, the recieved value(measVal), scales it to measured voltage(10-11V), corrects the offset and scales the new value to out max
285+
maxOut_tmp = int(round(range/((range+(float(measVal)/100))/maxOut)));
286+
} // if measVal is not 114('r')
287+
288+
maxOut = maxOut_tmp;
289+
290+
return maxOut;
291+
}
292+
293+
//_____________________________________________________________________________________________
294+
295+
void calibrateAO_func() { // Calibrate analogue PWM outs
296+
297+
int range = 0; // Range of values. Set to 10 or 20, depending on output channel
298+
if (channel == 0 or channel == 1){range = 20;} // For AO_0 and AO_1 with -10 to +10V range
299+
else {range = 10;} // For AO_2 and AO_3 with 0-10V range.
300+
301+
// Converted new maximum values for all four channels
302+
int new_max_AO0;
303+
int new_max_AO1;
304+
int new_max_AO2;
305+
int new_max_AO3;
306+
307+
if (newData == true) {
308+
switch (channel) {
309+
case 0:
310+
new_max_AO0 = calEq(range, chValConv, max_out_AO0);
311+
max_out_AO0 = new_max_AO0;
312+
break;
313+
case 1:
314+
new_max_AO1 = calEq(range, chValConv, max_out_AO1);
315+
max_out_AO1 = new_max_AO1;
316+
break;
317+
case 2:
318+
new_max_AO2 = calEq(range, chValConv, max_out_AO2);
319+
max_out_AO2 = new_max_AO2;
320+
break;
321+
case 3:
322+
new_max_AO3 = calEq(range, chValConv, max_out_AO3);
323+
max_out_AO3 = new_max_AO3;
324+
break;
325+
default:
326+
//Serial.println("NaN");
327+
break;
328+
} // Switch case channel
329+
330+
newData = false;
331+
} // if newData True
332+
}
333+
334+
335+
void LEDonoff(){
336+
if (LEDon == true) {digitalWrite(LED_BUILTIN, HIGH);} // switch the LED on}
337+
//else {digitalWrite(LED_BUILTIN, LOW);} // turn the LED off}
338+
} // Woid LEDonoff

autocad/.placeholder

Whitespace-only changes.

autocad/05t010vero.dwg

285 KB
Binary file not shown.

autocad/05tpm10vero.dwg

329 KB
Binary file not shown.

autocad/420t15vero.dwg

259 KB
Binary file not shown.

autocad/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# File Description
2+
3+
* [`05t010vero.dwg`](05t010vero.dwg): Stripboard layout for 0 − 5 V to 0 − 10 V converter circuit (editable file).
4+
* [`05tpm10vero.dwg`](05tpm10vero.dwg): Stripboard layout for 0 − 5 V to +- 10 V converter circuit (editable file).
5+
* [`420t05vero.dwg`](420t05vero.dwg): Stripboard layout for 4 - 20 mA to 0 − 5 V converter circuit (editable file).
6+
* [`pm10t05vero.dwg`](pm10t05vero.dwg): Stripboard layout for +- 10 V to 0 − 5 V converter circuit (editable file).
7+
* [`relaysvero.dwg`](relaysvero.dwg): Stripboard layout for 4-channel relay board (editable file).
8+
* [`fullWir.dwg`](fullWir.dwg): Full internal wiring diagram (editable file).
9+
* [`cBoxLayout.dwg`](cBoxLayout.dwg): Converter box xomponent layout / placement (editable file).

autocad/cBoxLayout.dwg

266 KB
Binary file not shown.

autocad/fullWir.dwg

270 KB
Binary file not shown.

0 commit comments

Comments
 (0)