-
Notifications
You must be signed in to change notification settings - Fork 0
2. Usage
First you need to connect a microcontroller via USB and then connect by creating an instance of the ArsemiCore with:
ArsemiCore _arsemiCore = ArsemiCore(int maximumSensorCount = 8);
From here you can connect it to the microcontroller with:
if(await _arsemiCore.ConnectMicrocontrollerAsync() != MessageParsing.ConnectionResult.SUCCESS) {
return
}
When the connection was successful the setup options can be sent to the arduino with (still buggy, don't use!):
_arsemiCore.FinishSetup();
Currently you still need to upload code to the arduino. For this you need to construct the same sensors with the same constructors and add them to the ArsemiCore in the Arsemi-Arduino code. This code then needs to be uploaded to an arduino with an USB-Cable.
When you want to start the execution of the ArsemiCore you call:
_arsemiCore.StartLoop();
Various sensors can be added to Arsemi. There exist a couple of interfaces to communicate between sensor and microcontroller. Most sensor have one specific interface they are using so look for keywords I2C, Analog, Digital or simply look into the arduino documentation for each sensor you intend to use.
For all the available sensors look in each category. The most common interfaces are:
Bus system in which multiple sensors can be connected via the SDA and SDL pins. If you have many sensors, you can connect all of them to the same pins because every sensor has his own address and Arduino will handle the correct communication. These sensors are more advanced because of the register-based architecture and need their own implementation (look below for the available sensors).
To wire an I2C sensor you need to connect a power source to VIN and GND, SDA and SDL to the according pins on the arduino. Depending on the arduino model the pins may vary (see Arduino Docs: Inter-Integrated Circuit (I2C) Protocol).
Many sensors can be used directly with the microcontroller as a power source, this means you can directly connect the VIN pins on arduino and sensor directly and any GND on the arduino to the GND on the sensor.
Example:
Source: Arduino Heart Rate Monitor Using MAX30102 and Pulse Oximetry
- MAX30102
Values of the sensor are in a certain voltage/resistance range. On the Arduino those values are in a range of 0-1023, Arsemi maps those readings to 1-255 for smaller binary package size. Any sensor which has an analog interface will work with this setup but the values may need some computation, according to the sensors datasheet to get a good value range (IMPORTANT! Arsemi remaps values from 0-1023 to 1-255).
The wiring for these sensors is really simple. Depending on the sensor there are 2 common options for the connection:
- Connect one side of the sensor to a power source (most likely the arduino's VIN or 3V pin) and the other side to any analog pin. This is the pin number you must supply as parameter when creating a sensor.
- Connect the sensors VIN to a power source (5V/VIN or external power source depending on the sensor) and the signal pin of the sensor to any analog pin. Some sensor require a different wiring, always look up the exact wiring before connecting the microcontroller to a power source.
Example:
Source: Interfacing The GSR Sensor to the Arduino to measure Resistance(Emotions)
- Potentiometer
- GSR (Skin resistance/sweat sensor)
- EMG (Muscle contraction)
- Photoresistor (Light sensor)
This interface is used for sensor who are either high/true or low/false. This means buttons and similar sensors can be used with it.
- Button
To setup any sensor you need to add one to the Arsemi-Core. The following example adds a new Analog Sensor (here a GSR-Sensor).
_arsemiCore.AddSensor(new AnalogSensor("GSR_Sensor", 0)).SetInterval(300);
With each sensor added to Arsemi it also stores its name. When accessing each sensor it's not possible to access them with their name to increase access speed (maybe added later). The first added sensor has the id 0 so you can access it this way but is unsafe and not recommended. The recommended way is to generate the ArsemiGlobals.cs file by calling await ConfigSaver.GenerateGlobals(ArsemiCore arsemiInstance, string pathToConfigDirectory) after you've added all the sensors to the Arsemi-Core. This file contains constants named like the name you've passed in the constructor of a sensor with the id as value. You can access each sensor as follows:
_arsemiCore.Sensors[int sensorId]
The current and last sensor values are stored in each sensor to access them you can call the following helper function.
_arsemiCore.GetSensorValue(int sensorId)
Alternatively the value can be directly accessed if you have the sensor stored from the creation.
Event can be added to each sensor. Every time a new sample arrives the event condition is checked and if it is true then the Action _arsemiCore.EventReceived is invoked.
Add an event by calling the following function on a sensor:
_sensor.AddEvent(string eventName, Predicate<RingBuffer> eventCondition)
You can pass your own function which checks values in the ringbuffer or use the event conditions from Arsemi.Sensor.Event.EventCondition. The available event conditions in that class are:
- Below Threshold
- Above Threshold
The following example adds an above threshold event to the GSR-Sensor:
_sensor.AddEvent("VerySweaty", rb => EventCondition.BelowThreshold(rb, 50))
If you then want to catch the event, you connect the _arsemiCore.EventReceived to a function in which you check against what event has been invoked. Example:
public static void HandleEvent(EventData eventData) {
if(eventData.Name == "VerySweaty") {
// insert handling of the event here
}
}
Filters can be applied to the raw data to filter out unwanted flickering or smooth it. Each sensor has its own stack of filters which are applied one after another. You can add one of the pre-made filters with the following:
_sensor.AddFilter(FilterAliases.ButterworthHighPassFilter(100, 10), "Highpass");
Available Filters:
AbstractFilter ButterworthLowPassFilter(float samplingRate, float frequency)AbstractFilter ButterworthHighPassFilter(float samplingRate, float frequency)AbstractFilter NotchBandpassBandrejectFilter(float samplingRate, float frequency, float bandwidth)- Generic filter (you must compute all the values so it's harder to use):
AbstractFilter IIRFilter(float a0in, float a1in, float a2in, float b1in, float b2in)