|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Did you know...
|
Serial Wombat 2D Lookup Table Channel ModeThe 2D Lookup Table Channel Mode allows the user to provide an input/output transfer function based on an arbitrary number of x/y points. The 2D Lookup can be used in an input mode to modify provided public data on channels that can read analog inputs. The 2D Lookup can also be used in an output mode to drive a PWM or Analog output based on the result of running The lookup table itself is provided by the host. It consists of two or more x/y (or input/output) pairs of 16-bit numbers. The x value of the first point in the table must be 0. The x value of the last point in the table must be 65535. Points in the table must be in ascending x order. All y values may be any value between 0 and 65535. When the Wombat performs the lookup for a given input, it searches through the table to find the two consecutive x values between which the input falls. Depending on how the channel mode is set up, it then either returns the lower value, or performs a linear interpolation to provide a proportional output based on the input. This is most easily explained by examples. See the Section below for examples of how to use this pin mode. Message format:The message format for the 2D lookup table channel mode consists of two messages. The first message tells the Wombat a number of things:
The second message tells the the Wombat whether or not to output the result of the lookup as an Analog/PWM value on the pin being configured. Note that a pin cannot be both the input (set in the previous message). By default message 200 turns off output. Sending message 201 is not necessary unless output on is desired.
The third message is used in cases where the pin being configured as a 2D Lookup table is an intermediate step between two other pins. In this case it may be desireable for the host to use this pin's physical hardware as a general-purpose I/O. See below for an example.
Example 1: Changing the range of a servo by remapping through a lookup tableConsider a simple case where a 0 to 5 Volt voltage source is connected to Wombat pin 2. If pin 2 is configured for Analog
Input raw mode, then a value from 0 to 65535 will be reported
as public data.
Figure 1: Pin 16 positions a Servo based on Pin 2's Public Data The arangement in the diagram above will allow the user to position the servo by turning the pot. However, this assumes that the user wants the entire range of the potentiometer to correspond to the entire range of the servo, in a 1:1 ratio. This may not be true. If only a smaller amount of movement is desired on the servo (say only 90 degrees out of a possible 180), then this direct correlation is not desirable. It's better to use the entire range of the pot to represent only 1/2 of the range of the servo. In order to achieve this, a lookup table can be used. The goal of this lookup table will be to map pin 2's analog input from a range of 0 to 65535 to an output range of 16384 to 49151. This range will reduce the servo's total motion by half, but still keep it centered when the knob is centered.
The table for Graph 1 is quite simple:
This table would require 8 bytes in RAM (2 for each number). Commands: 146 0x0030 4 0x0000 0x4000 ; Place first point in memory at address
; 0x0030
; Length 4 bytes
; Data: 0x00 0x00 0x40 0x00
146 0x0034 4 0xFFFF 0xBFFF ; Place second point in memory at address
; 0x0034
; Length 4 bytes
; Data: 0xFF 0xFF 0xBF 0xFF
200 2 25 0x0030 2 1 1 ; Configure pin 2 to 2D lookup
; Lookup table located at address
; 0x0030
; Based on input from pin 2
; 1 = Interpolate
; 1 =
200 16 17 0x0FA0 0x36B0 2 ; Set pin 16 to servo mode,
; Minimum pulse 4000 ticks (0x0FA0)
; Variable period 14000 ticks (0x36B0)
; Read pin 2's data for position
201 16 17 0x8000 19 0 0x55 ; Second configuration message, pin 16 to servo mode
; Set position to 0x8000 (middle pulse width)
; 19 frames (ms) between updates
; 0 = don't invert position command
; last byte is unused
Suppose that it is desired to reverse the direction of the servo. That is to say, if a clockwise rotation of the potentiometer knob previously caused a clockwise rotation of the servo, then that direction is desired to be reveresed. This can easily be accomplished by changing the transfer function of the lookup table:
Graph 2: Transfer function to map 0 to 65535 count input to 49151 to 16384 count output The table for Graph 2:
Note that.comprared to figure 1's table, the Y values have changed places, but the X values have not. 146 0x0030 4 0x0000 0xBFFF ; Place first point in memory at address
; 0x0030
; Length 4 bytes
; Data: 0x00 0x00 0xBF 0xFF
146 0x0034 4 0xFFFF 0x4000 ; Place second point in memory at address
; 0x0034
; Length 4 bytes
; Data: 0xFF 0xFF 0x40 0x00
200 2 25 0x0030 2 1 1 ; Configure pin 2 to 2D lookup
; Lookup table located at address
; 0x0030
; Based on input from pin 2
; 1 = Interpolate
; 1 = Table in RAM
200 16 17 0x0FA0 0x36B0 2 ; Set pin 16 to servo mode,
; Minimum pulse 4000 ticks (0x0FA0)
; Variable period 14000 ticks (0x36B0)
; Read pin 2's data for position
201 16 17 0x8000 19 0 0x55 ; Second configuration message, pin 16 to servo mode
; Set position to 0x8000 (middle pulse width)
; 19 frames (ms) between updates
; 0 = don't invert position command
; last byte is unused
Example 2: Changing PWM output to an LED to appear linearA typical LED (I'll use a bargain basement Red one for this example, the sort you can get for 2 cents each) has a non-linear relationship between current and brightness. This may make it unsuitable as an indicator representing the state of some other Wombat input. We'll use a lookup table to linearize it. I'm going to connect my LED to Wombat pin 16 and ground, so that I can control it using a high resolution PWM signal. I'll attach a 220 ohm resistor between ground and the LED to limit the current.
Figure 2: An LED is lit with PWM based on the result of a table lookup of the public data from Pin 2 I'll use the WombatPanel PWM option to try different PWM outputs to the LED, and try to get some idea of how the apparent brightness compares to the average current through the LED as provided by the PWM signal. At only 1% PWM the LED has a dim, but quite visible glow to it. The following is my attempt to find points where the apparent brightness has doubled. I don't have any way to measure this scientifically, so I'm going to eyeball it. Your opinion of what constitutes a doubling of brightness may vary.
These points (again, very subjective), tend to indicate that you get a good brightness return on your current at low currents, and a poor brightness return on your current at high currents. A graph of the brightness of this LED against its current might then look like roughly like this (plotted with straight lines and a 3rd order best fit curve):
Graph 3: Apparent Brightness of an LED vs. Current Since the maximum relative brightness is 35, half of that is 17. 17 occurs at around a 27% PWM output. What we would like to do it provide a remapping which will allow some other pin, such as a voltage source connected to pin 2, to indicate its setting through PWM brightness. In order to do this, we must build our output table. We want zero input to map to zero brightness, so we'll have one point (0,0). an input of 65535 should have an output of 100% brightness, (or 35 in the graph above), so we'll add another point (65535, 65535). An input of 32,768 should have a brightness of 50%. In order to determine the PWM percentage for 50%, we'll go to the best fit graph, and look to see where the graph crosses 17.5. This value is approximately 27.5. Therefore, the next point will be .275 * 65535, or 18022. We'll find points for each 10% of brightness off the line:
Creating a table which maps PWM to brightness (effectively the inverse of the table above) gives the following:
Graph 4: Transfer function to linearize LED brighness
An experiment with this table shows that the LED does in fact increase in brightness fairly evenly as the knob attached to pin 2 is turned. 146 0x0060 4 0x0000 0x0000 ; Place first point in memory at address
; 0x0060
; Length 4 bytes
; Data: 0x00 0x00 0x00 0x00
146 0x0064 4 0x199A 0x0A3D 146 0x0068 4 0x3333 0x170A 146 0x006C 4 0x4CCD 0x9503 146 0x0070 4 0x6666 0x347B 146 0x0074 4 0x8000 0x47AE 146 0x0078 4 0x9999 0x5C28 146 0x007C 4 0xB333 0x75C2 146 0x0080 4 0xCCCC 0x9709 146 0x0084 4 0xE666 0xC7AD 146 0x0088 4 0xFFFF 0xFFFF ; Place last point in memory at address
; 0x0088
; Length 4 bytes
; Data: 0xFF 0xFF 0xFF 0xFF
200 2 6 0x55 0x55 0x55 0x55 0x55 ; Configure pin 2 Raw A/D Conversion 200 2 25 0x0060 2 1 1 ; Configure pin 2 to 2D lookup
; Lookup table located at address
; 0x0060
; Based on input from pin 2
; 1 = Interpolate
; 1 = Table in RAM
201 2 25 1 0x55 0x55 0x55 0x55 ; Configure pin 25 to 2D lookup
; Enable PWM / Analog output
Example 3: Warning Buzzer which Sounds if input is too high or too low.In this example a small, low current piezo buzzer is attached to pin 10 and ground. This buzzer will sound if pin 10 goes high. It is desired to have the buzzer sound if the public data from pin 2 drops below 10000, or goes above 50000. In this case we will create a transfer function which is either high or low, with no steps in between. Additionally, we will turn off interpolation, since we don't want any scaling of the output between points.
Graph 4: Transfer function to set a pin high at low and high ends of an input This is a very simple set of points:
Note that this set of points will only work if Interpolation is turned off. Otherwise, the graph will be a series of sloped lines. In this example the final point (65535,65535) doesn't really add any useful information to the table. However, it is necessary so the Wombat knows that no additional points follow (50000,65535). 146 0x0070 4 0x0000 0xFFFF ; Place first point in memory at address
; 0x0070
; Length 4 bytes
; Data: 0x00 0x00 0xFF 0xFF
146 0x0074 4 0x2710 0x0000 146 0x0078 4 0xC350 0xFFFF 146 0x007C 4 0xFFFF 0xFFFF ; Place last point in memory at address
; 0x007C
; Length 4 bytes
; Data: 0xFF 0xFF 0xFF 0xFF
200 2 6 0x55 0x55 0x55 0x55 0x55 ; Configure pin 2 Raw A/D Conversion 200 2 25 0x0060 2 1 1 ; Configure pin 2 to 2D lookup
; Lookup table located at address
; 0x0070
; Based on input from pin 2
; 0 = Don't Interpolate
; 1 = Table in RAM
201 2 25 1 0x55 0x55 0x55 0x55 ; Configure pin 25 to 2D lookup
; Enable PWM / Analog output
Example 4: Using a Lookup table as an intermediate step.Sometimes it may be desired to use a lookup table to drive some non-pwm/analog output based on the result of another processed pin. In this case it is possible to put a lookup table in-between two pins. Since all processing must be associated with a pin, this requires the use of a third pin, despite the fact that the actual physical connection to this pin will not serve any purpose. Suppose that the voltage source being fed to pin 2 in Example 1 above is noisy. This would cause the servo to jitter even if the knob on the Potentiometer is not actually being adjusted. To compensate for that we can apply filtering to the input of pin 2 by putting it in a filter mode. However, a pin cannot be configured for both filtering and table lookup at the same time. Similarly, the output pin cannot be configured for both lookup table and servo control at the same time. The soultion to this problem is to use a third pin as an intermediate step between the filtered input and the servo output. This pin will be used only for its ability to transform public data within the Wombat. The actual physical pin will serve no purpose.
Figure 3: Filtered data from pin 2 is transformed by pin 10 before being passed to pin 16 for servo output We'll use the same table as in Example 1 above.
This table would require 8 bytes in RAM (2 for each number). Commands: 146 0x0030 4 0x0000 0x4000 ; Place first point in memory at address
; 0x0030
; Length 4 bytes
; Data: 0x00 0x00 0x40 0x00
146 0x0034 4 0xFFFF 0xBFFF ; Place second point in memory at address
; 0x0034
; Length 4 bytes
; Data: 0xFF 0xFF 0xBF 0xFF
200 2 7 0xBC6A 0 0x55 0x55 ; Configure pin 2 to 1st order filtering
; Filter constant .736
; Sample every frame.
200 10 25 0x0030 2 1 1 ; Configure pin 10 to 2D lookup
; Lookup table located at address
; 0x0030
; Based on input from pin 2
; 1 = Interpolate
; 1 = Table in RAM
200 16 17 0x0FA0 0x36B0 10 ; Set pin 16 to servo mode,
; Minimum pulse 4000 ticks (0x0FA0)
; Variable period 14000 ticks (0x36B0)
; Read pin 10's data for position
201 16 17 0x8000 19 0 0x55 ; Second configuration message, pin 16 to servo mode
; Set position to 0x8000 (middle pulse width)
; 19 frames (ms) between updates
; 0 = don't invert position command
; last byte is unused
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Copyright Wombat Interface Products, 2005-2008. All Rights Reserved.