Hubo Library

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
AnalogRawInput.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <assert.h>
4
5 #include "../hubolib.h"
6
7 using namespace HuboLib;
8
9 /*
10 Compile and link:
11 g++ AnalogRawInput.cpp -L../ -lhubo -lpthread -lrt -o AnalogRawInput.out
12 Run:
13 sudo ./AnalogRawInput.out
14 Purpose:
15 Sometimes it is necessary to follow an analog signal once it reaches a certain threshold. Since the Linux scheduler
16 cannot work efficient at higher rates than 1ms further decreasing of the cycle time would not help. Too much
17 time would be wasted due to thread context changes...
18 However, from within any of the callbacks provided by the library it is save to call Get_AI_Channel_Raw() in order
19 to low level access the MCP3208/MCP3008 chips. You can for example poll the converters in a loop in order to
20 achieve a higher resolution or save values in an array for later evaluation (e.g. by the main thread).
21 Make sure to not use Get_AI_Channel_Raw() from any other thread but the libraries background thread!
22 Maximum frequencies that can be achieved this way are around 8kHz. However, note that nearly no other application
23 will run during the "blocking" of a callback function due to the high priority it runs at!
24 */
25
26 void CycleTickCallback (unsigned long* pADChannelValues, unsigned char* pDigitalInputValues, unsigned char* pDigitalOutputValues);
27 double DigitToVolt (unsigned long digit);
28
29 int main(void)
30 {
31 // Initialize the library once in your program.
32 if (!Initialize())
33 {
34 printf ("Error: Initialize\n");
35 return 1;
36 }
37
38 // Note - in order to access raw AD valued you do not need to setup oversampling!
39 // This avoids overhead if for example just the voltage of a power supply should get monitored in the background!
40
41 // Let's sample every 1s (1Hz).
42 Set_Cycle_Time (1000);
43
44 // Register the callback.
45 Register_CycleTickCallback (CycleTickCallback);
46
47 // Let the main thread run a while... in between use the cycle tick callback for latching analog values.
48 for (int i=0; i<10; i++)
49 {
50 printf ("Main thread waiting...\n");
51 usleep(1000000);
52 }
53
54 // Once not needed anymore the callbacks can be unregistered.
55 Unregister_CycleTickCallback (CycleTickCallback);
56
57 // Free library resources.
58 Uninitialize();
59
60 return 0;
61 }
62
63 void CycleTickCallback (unsigned long* pADChannelValues, unsigned char* pDigitalInputValues, unsigned char* pDigitalOutputValues)
64 {
65 // Usually we'd avoid lengthily operations in callback routines as this would lead the cycle tick to get broken.
66 // However, this time we wait for an analog signal to be within the range of 1.4V and 1.6V. If we detect such a signal
67 // We latch 1000 values as fast as we can and compute the average of them.
68
69 printf ("CycleTickCallback called.\n");
70
71 // Note that we do not need to have valid values in pADChannelValues nor do we need to access it (...while we could of cause...).
72 unsigned short value = 0;
73 if (!Get_AI_Channel_Raw (0, value))
74 {
75 printf ("Failed to retrieve analog value from MCP3x08.\n");
76 assert (false);
77 return;
78 }
79
80 double currentVolt = DigitToVolt(value);
81
82 printf ("Rough value = %lf\n", currentVolt);
83
84 // Within the range of 1.4V to 1.6V we retrieve raw values as fast as we can.
85 // Maybe because we need to follow a signal faster than our usual cycle time...
86 if (currentVolt < 1.4 || currentVolt > 1.6)
87 return;
88
89 // In order to get here connect a 1.5V battery to analog input 0.
90
91 unsigned long currentValue = 0;
92 int channel = 0;
93
94 unsigned long long startTime = GetTime_MicroSeconds();
95
96 // Latch 1000 samples.
97 for (int i=0; i<1000; i++)
98 {
99 if (Get_AI_Channel_Raw (0, value))
100 currentValue += value;
101 else
102 {
103 printf ("Failed to retrieve analog value from MCP3x08.\n");
104 assert (false);
105 return;
106 }
107 }
108 unsigned long long stopTime = GetTime_MicroSeconds();
109
110 printf ("Precise value = %lf duration = %lfms (at 1000 samples).\n", DigitToVolt(currentValue)/1000.0, (stopTime-startTime)/1000.0);
111
112 // Output of a 1.5V battery that has been observed.
113 // Rough value = 1.502805
114 // Precise value = 1.502918 duration = 119.265000ms (at 1000 samples).
115 }
116
117 // Helper: Convert the digits into a voltage.
118 double DigitToVolt(unsigned long digit)
119 {
120 // We have a resolution of 4096 digit for the MCP3208, 1024 digit for the MCP3008.
121 return (((double)digit)*Get_VRef()/4096.0);
122 }
123
HuboLib::Initialize
bool Initialize()
Initializes the library.
HuboLib::Get_AI_Channel_Raw
bool Get_AI_Channel_Raw(int channel, unsigned short &value)
Gets an unbuffered value from the MCP3x08.
HuboLib::Get_VRef
double Get_VRef()
Retrieves the reference voltage value used for ADC count convertion.
HuboLib::Set_Cycle_Time
bool Set_Cycle_Time(long cycleTime)
Sets the backgrounds threads polling interval in ms.
main
int main(void)
Definition: AnalogRawInput.cpp:29
HuboLib::Unregister_CycleTickCallback
bool Unregister_CycleTickCallback(T_pfn_CycleTickCallback pFnCycleTickCallback)
Unregister a callback previouly registered by a call to Register_CycleTickCallback().
CycleTickCallback
void CycleTickCallback(unsigned long *pADChannelValues, unsigned char *pDigitalInputValues, unsigned char *pDigitalOutputValues)
Definition: AnalogRawInput.cpp:63
DigitToVolt
double DigitToVolt(unsigned long digit)
Definition: AnalogRawInput.cpp:118
HuboLib::Uninitialize
void Uninitialize()
Releases any resources bound to the library.
HuboLib::GetTime_MicroSeconds
unsigned long long GetTime_MicroSeconds()
Returns the number of micro seconds.
HuboLib::Register_CycleTickCallback
bool Register_CycleTickCallback(T_pfn_CycleTickCallback pFnCycleTickCallback)
Registers a callback function called on every cycle tick.
HuboLib
Definition: hubocfg.h:10