-
Notifications
You must be signed in to change notification settings - Fork 56
/
genieArduino_Demo.ino
168 lines (141 loc) · 9.24 KB
/
genieArduino_Demo.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <genieArduino.h>
// This Demo communicates with a 4D Systems Display, configured with ViSi-Genie, utilising the Genie Arduino Library - https://github.com/4dsystems/ViSi-Genie-Arduino-Library.
// The display has a slider, a cool gauge, an LED Digits, a string box and a User LED. Workshop4 Demo Project is located in the /extras folder
// The program receives messages from the Slider0 object using the Reported Events. This is triggered each time the Slider changes on the display, and an event
// is genereated and sent automatically. Reported Events originate from the On-Changed event from the slider itself, set in the Workshop4 software.
// Coolgauge is written to using Write Object, and the String is updated using the Write String command, showing the version of the library.
// The User LED is updated by the Arduino, by first doing a manual read of the User LED and then toggling it based on the state received back.
// As the slider changes, it sends its value to the Arduino (Arduino also polls its value using genie.ReadObject, as above), and the Arduino then
// tells the LED Digit to update its value using genie.WriteObject. So the Slider message goes via the Arduino to the LED Digit.
// Coolgauge is updated via simple timer in the Arduino code, and updates the display with its value.
// The User LED is read using genie.ReadObject, and then updated using genie.WriteObject. It is manually read, it does not use an Event.
// This demo illustrates how to use genie.ReadObject, genie.WriteObject, Reported Messages (Events), genie.WriteStr, genie.WriteContrast, plus supporting functions.
// Application Notes on the 4D Systems Website that are useful to understand this library are found: https://docs.4dsystems.com.au/app-notes
// Good App Notes to read are:
// ViSi-Genie Connecting a 4D Display to an Arduino Host - https://docs.4dsystems.com.au/app-note/4D-AN-00017/
// ViSi-Genie Writing to Genie Objects Using an Arduino Host - https://docs.4dsystems.com.au/app-note/4D-AN-00018/
// ViSi-Genie A Simple Digital Voltmeter Application using an Arduino Host - https://docs.4dsystems.com.au/app-note/4D-AN-00019/
// ViSi-Genie Connection to an Arduino Host with RGB LED Control - https://docs.4dsystems.com.au/app-note/4D-AN-00010/
// ViSi-Genie Displaying Temperature values from an Arduino Host - https://docs.4dsystems.com.au/app-note/4D-AN-00015/
// ViSi-Genie Arduino Danger Shield - https://docs.4dsystems.com.au/app-note/4D-AN-00025
Genie genie;
#define RESETLINE 4 // Change this if you are not using an Arduino Adaptor Shield Version 2 (see code below)
void setup()
{
// Use a Serial Begin and serial port of your choice in your code and use the
// genie.Begin function to send it to the Genie library (see this example below)
// 200K Baud is good for most Arduinos. Galileo should use 115200.
// Some Arduino variants use Serial1 for the TX/RX pins, as Serial0 is for USB.
Serial.begin(200000); // Serial0 @ 200000 (200K) Baud
genie.Begin(Serial); // Use Serial0 for talking to the Genie Library, and to the 4D Systems display
genie.AttachEventHandler(myGenieEventHandler); // Attach the user function Event Handler for processing events
// Reset the Display (change D4 to D2 if you have original 4D Arduino Adaptor)
// THIS IS IMPORTANT AND CAN PREVENT OUT OF SYNC ISSUES, SLOW SPEED RESPONSE ETC
// If NOT using a 4D Arduino Adaptor, digitalWrites must be reversed as Display Reset is Active Low, and
// the 4D Arduino Adaptors invert this signal so must be Active High.
pinMode(RESETLINE, OUTPUT); // Set D4 on Arduino to Output (4D Arduino Adaptor V2 - Display Reset)
digitalWrite(RESETLINE, 1); // Reset the Display via D4
delay(100);
digitalWrite(RESETLINE, 0); // unReset the Display via D4
// Let the display start up after the reset (This is important)
// Increase to 4500 or 5000 if you have sync problems as your project gets larger. Can depent on microSD init speed.
delay (3500);
// Set the brightness/Contrast of the Display - (Not needed but illustrates how)
// Most Displays use 0-15 for Brightness Control, where 0 = Display OFF, though to 15 = Max Brightness ON.
// Some displays are more basic, 1 (or higher) = Display ON, 0 = Display OFF.
genie.WriteContrast(10); // About 2/3 Max Brightness
//Write to String0 on the Display to show the version of the library used
genie.WriteStr(0, GENIE_VERSION);
//OR to illustrate (comment out the above, uncomment the below)
genie.WriteStr(0, (String) "Hello 4D World");
}
void loop()
{
static unsigned long waitPeriod = millis();
static int gaugeAddVal = 1; // Simulation code variable. Value to change the gauge by each loop
static int gaugeVal = 50; // Simulation code variable. Value to start the gauge at when powered on
genie.DoEvents(); // This calls the library each loop to process the queued responses from the display
if (millis() >= waitPeriod)
{
// Write to CoolGauge0 with the value in the gaugeVal variable
genie.WriteObject(GENIE_OBJ_COOL_GAUGE, 0, gaugeVal);
// Simulation code, just to increment and decrement gauge value each loop, for animation
gaugeVal += gaugeAddVal;
if (gaugeVal == 99) gaugeAddVal = -1;
if (gaugeVal == 0) gaugeAddVal = 1;
// The results of this call will be available to myGenieEventHandler() after the display has responded
genie.ReadObject(GENIE_OBJ_USER_LED, 0); // Do a manual read from the UserLEd0 object
waitPeriod = millis() + 50; // rerun this code to update Cool Gauge and Slider in another 50ms time.
}
}
/////////////////////////////////////////////////////////////////////
//
// This is the user's event handler. It is called by genieDoEvents()
// when the following conditions are true
//
// The link is in an IDLE state, and
// There is an event to handle
//
// The event can be either a REPORT_EVENT frame sent asynchronously
// from the display or a REPORT_OBJ frame sent by the display in
// response to a READ_OBJ (genie.ReadObject) request.
//
/* COMPACT VERSION HERE, LONGHAND VERSION BELOW WHICH MAY MAKE MORE SENSE
void myGenieEventHandler(void)
{
genieFrame Event;
genie.DequeueEvent(&Event);
int slider_val = 0;
//Filter Events from Slider0 (Index = 0) for a Reported Message from Display
if (genie.EventIs(&Event, GENIE_REPORT_EVENT, GENIE_OBJ_SLIDER, 0))
{
slider_val = genie.GetEventData(&Event); // Receive the event data from the Slider0
genie.WriteObject(GENIE_OBJ_LED_DIGITS, 0, slider_val); // Write Slider0 value to LED Digits 0
}
//Filter Events from UserLed0 (Index = 0) for a Reported Object from Display (triggered from genie.ReadObject in User Code)
if (genie.EventIs(&Event, GENIE_REPORT_OBJ, GENIE_OBJ_USER_LED, 0))
{
bool UserLed0_val = genie.GetEventData(&Event); // Receive the event data from the UserLed0
UserLed0_val = !UserLed0_val; // Toggle the state of the User LED Variable
genie.WriteObject(GENIE_OBJ_USER_LED, 0, UserLed0_val); // Write UserLed0_val value back to UserLed0
}
} */
// LONG HAND VERSION, MAYBE MORE VISIBLE AND MORE LIKE VERSION 1 OF THE LIBRARY
void myGenieEventHandler(void)
{
genieFrame Event;
genie.DequeueEvent(&Event); // Remove the next queued event from the buffer, and process it below
int slider_val = 0;
//If the cmd received is from a Reported Event (Events triggered from the Events tab of Workshop4 objects)
if (Event.reportObject.cmd == GENIE_REPORT_EVENT)
{
if (Event.reportObject.object == GENIE_OBJ_SLIDER) // If the Reported Message was from a Slider
{
if (Event.reportObject.index == 0) // If Slider0 (Index = 0)
{
slider_val = genie.GetEventData(&Event); // Receive the event data from the Slider0
genie.WriteObject(GENIE_OBJ_LED_DIGITS, 0, slider_val); // Write Slider0 value to LED Digits 0
}
}
}
//If the cmd received is from a Reported Object, which occurs if a Read Object (genie.ReadOject) is requested in the main code, reply processed here.
if (Event.reportObject.cmd == GENIE_REPORT_OBJ)
{
if (Event.reportObject.object == GENIE_OBJ_USER_LED) // If the Reported Message was from a User LED
{
if (Event.reportObject.index == 0) // If UserLed0 (Index = 0)
{
bool UserLed0_val = genie.GetEventData(&Event); // Receive the event data from the UserLed0
UserLed0_val = !UserLed0_val; // Toggle the state of the User LED Variable
genie.WriteObject(GENIE_OBJ_USER_LED, 0, UserLed0_val); // Write UserLed0_val value back to UserLed0
}
}
}
/********** This can be expanded as more objects are added that need to be captured *************
*************************************************************************************************
Event.reportObject.cmd is used to determine the command of that event, such as an reported event
Event.reportObject.object is used to determine the object type, such as a Slider
Event.reportObject.index is used to determine the index of the object, such as Slider0
genie.GetEventData(&Event) us used to save the data from the Event, into a variable.
*************************************************************************************************/
}