Arduino Driver guide: Difference between revisions
Jump to navigation
Jump to search
Line 68: | Line 68: | ||
def apply(self): | def apply(self): | ||
# self.value is always the actual value to be set, print to see exact format | |||
print(self.value) | |||
self.port.write("Voltage=" + str(self.value)) | # here we send the new command to the Arduino | ||
self.port.write("Voltage=" + str(self.value)) | |||
def reach(self): | def reach(self): | ||
# read out the COM port to know that the Arduino has finished setting the parameter. Only use it if the Arduino sends a response. | |||
self.port.read() | |||
def measure(self): | def measure(self): | ||
# send some command to request a reading of parameters, for example "Read?" or any other command. Only use it if the Arduino can read parameters | |||
self.port.write("Read?") | |||
def call(self) | def call(self): | ||
self.answer = self.port.read() | # read out the COM port | ||
self.answer = self.port.read() | |||
# return the answer to SweepMe!. Do not forget to transform the string to any format as needed e.g. float or integer | |||
return [float(self.answer)] | |||
}} | }} | ||
Latest revision as of 12:03, 9 December 2022
Using existing Drivers
Already existing Arduino Drivers, e.g. implemented as Logger or Switch, can be used after configuring the Arduino.
- Install the ArduinoIDE
- For every Driver, there exists one ".ino" file which can be found in the corresponding Driver folder
- Double-click the ".ino" file and the ArduinoIDE will open
- Configure your ArduinoIDE by setting the Arduino type (e.g. nano, uno, or mega) and the COM port
- Upload the ".ino" file to the Arduino
- Now your Arduino knows how to handle the commands send by the SweepMe! Driver
Creating an own Driver for Arduino
Arduino can easily be combined with SweepMe! However, there are some guidelines which make the implementation much easier:
- Try to sends a text during the setup() routine of the Arduino, so that SweepMe! knows that sending commands can be done from now on.
- The Arduino can send text via its function println() which uses a LineFeed character as terminator ("\n"). Thus, the Arduino should also expect to receive messages ending with a LineFeed ("\n") so that the write and read terminators are identical. The standard terminator of SweepMe! is a LineFeed ("\n") so that you do not have to set it.
- If the Arduino sends a message back after receiving a command, do not send more than one line. Otherwise, one has to read out the COM port multiple times in the SweepMe! Driver
- Try to have a constant length or format of the return message, so that reading out the string is less errorneous
- Try to make every parameter adjustable by a single command, e.g. "Pixel = 03", "Voltage = 0.05", or "Frequency = 400". That way, multiple items of the sequencer can communicate with the Arduino and multiple parameters can be swept.
- Use the standard baudrate of 9600 so that other Arduino Drivers can easily be copied and modified.
- After finishing your Driver, put your ino file as uploaded to the Arduino into the folder of the Driver. Give the ino file exactly the same name as used for the folder to allow for easy manipulation using the Arduino IDE.
Example Driver
Arduinos are typically implemented as Switch if you rather set some values or as Logger if your rather read some value. The following code shows a Driver which can set and read a value.
from EmptyDeviceClass import EmptyDevice # Loading the EmptyDevice Class
class Device(EmptyDevice): # Creating a new Device Class by inheriting from EmptyDevice
def __init__(self): # The python class object need to be initialized
EmptyDevice.__init__(self) # Finally, the initialization of EmptyDevice has to be done
self.variables = ["A variable to read out"]
self.units = ["The unit of the variable"]
self.plottype = [True] # set to False if the variable is a string and cannot be plotted
self.savetype = [True] # set to False if there is no need to save the variable to the data file
self.port_manager = True # using the port manager works seamlessly
self.port_types = ["COM"] # Arduinos are always listed as COM ports
self.port.properties = {
"timeout" : 2, # set timeout of the COM port to 2 seconds, which is necessary to prevent timeout error during initialization
}
def set_GUIparameter(self):
# fill your gui parameters here
gui_parameters = {
}
return gui_parameters
def get_GUIparameter(self, parameters):
self.driver_name = parameters['Device']
self.port_string = parameters['Port']
def initialize(self):
# unique identifier for each device
identifier = self.driver_name + "_" + self.port_string
# we only wait once, e.g. if the driver is used in multiple modules with the same device
if identifier not in self.device_communication:
self.port.read() # readout the COM port to know that the Arduino is ready to receive commands
# It will read out the "Arduino initialized" that the Arduino sends in the .ino file below
self.device_communication[identifier] = None # just to add a key to the dictionary
def apply(self):
# self.value is always the actual value to be set, print to see exact format
print(self.value)
# here we send the new command to the Arduino
self.port.write("Voltage=" + str(self.value))
def reach(self):
# read out the COM port to know that the Arduino has finished setting the parameter. Only use it if the Arduino sends a response.
self.port.read()
def measure(self):
# send some command to request a reading of parameters, for example "Read?" or any other command. Only use it if the Arduino can read parameters
self.port.write("Read?")
def call(self):
# read out the COM port
self.answer = self.port.read()
# return the answer to SweepMe!. Do not forget to transform the string to any format as needed e.g. float or integer
return [float(self.answer)]
Example Arduino .ino file
The following code shows you an example how to implement the above guidelines into an Arduino ino file. It has to be adapted to your needs.
// define some variables
unsigned int variable1;
String command; // the variable command
// define functions which you need later
void myFunction()
{
variable1++;
}
//
void setup()
{
// configure your pins here
Serial.begin(9600); // set Arduino to baudrate 9600
// Serial.setTimeout(1000); // change timeout if necessary, default is 1000 ms
Serial.println("Arduino initialized"); // send some text to let SweepMe! know that the Arduino has finished the setup() function
}
void loop ()
{
// check whether some command has been received at the COM port
if (Serial.available()) {
command = Serial.readStringUntil('\n'); // make sure you have '\n', "\n" does not work
if (command == "Read?") {
// sending back the answer.
Serial.print("some text");
Serial.print("some further text");
Serial.println(""); // you can send multiple times using print, but only send println to reply with a single message after each command
}
// if the command starts with some special text you can
else if (command == "Voltage?") {
// use some functions to get the parameter 'voltage' and return it
voltage = some_function_to_retrieve_the_voltage_value();
Serial.println(voltage); // here we send the value, the command 'println' adds a Line Feed character ('\n') to each message automatically
}
// if the command starts with some special text you can
else if (command.startsWith("Voltage=")) {
// split the value from the command here and change the parameter accordingly
float set_voltage = command.substring(command.indexOf('=')+1).toFloat();
my_voltage_function(set_voltage); // here you need to run any function that changes the voltage
Serial.println("Voltage=..."); // reply to let SweepMe! know that the parameter is changed.
}
else if (command == "Frequency?") {
// split the value from the command here and change the parameter accordingly
frequency = some_function_to_retrieve_the_frequency_value();
Serial.println(frequency); // reply to let SweepMe! know that the parameter is changed
}
else if (command.startsWith("Frequency=")) {
// split the value from the command here and change the parameter accordingly
int set_frequency = command.substring(command.indexOf('=')+1).toInt();
my_frequency_function(set_frequency); // here you need to run any function that changes the voltage
Serial.println("Frequency=..."); // reply to let SweepMe! know that the parameter is changed
}
}
}