Serial Wombat
a general-purpose digital interface device for hobbyists, engineers and students

 


Home
Overview
Protocol
Documentation
Channel Modes
Direct Control
Controlled Pin
Raw A/D
A/D Averaging
A/D 1st Order Filtering
Matrix Keypad
Servo Control
Analog Direct
Analog Follow
Rotary Encoder
Debouncing
Counter
Hysteresis
Morse Code
Pulse
Unipolar Stepper
LCD Driver 1
LCD Driver 2
HW Pulse Meas.
2D Lookup
SPI Master
HD44780 Generic
Remote Control
DataLogger
Min-Max
Public Data
Timed IO
Getting Started
Connectivity
Pin Mode SDK Beta
Sample Projects
Downloads
Contact Us
Purchase
Forum

Did you know...

 

Serial Wombat 2D Lookup Table Channel Mode

The 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 address in User RAM area of the lookup table. This table must be entered into User RAM before the pin is configured for 2D Lookup table mode. The Wombat firmware will verify that the first X entry in the table is 0x0000, and that the second X entry is not 0x0000. No further error checking will be done. It is the responsiblity of the host to insure that X/Y tables conform to the requirements above.
  • The pin providing the X value to be transformed to the Y value. Most often this will be a pin providing an A/D conversion, but any pin's public data, or public data sources not associated with a pin (such as receive count) may be used. An A/D capable pin can be configured for 2D Lookup mode with itself as a data source. When configured this way the transform will be performed on the analog voltage measured by that pin.
  • Whether or not to interpolate between points. When interpolation is turned on, a linear interpolation will be performed on X values which fall between two points. When turned off, the Y value associated with the lower of the two points will be returned. The graph of an interpolated transform often looks like a series of slanted lines. The graph of a transform without interpolation looks like a series of stair steps.
  • Where the table is stored. Future versions of the Wombat may allow tables to be stored in Flash or EEPROM. Currently tables can only be stored in RAM.
Data Sent to the Wombat: 200 Pin # 25 Table Address High Byte Table Address Low Byte X value (input) Pin # Interpolate Table Location (set to 1 )
Meaning: Configure Pin First message Pin Number to be set to 2D Lookup Table Channel Mode 2D Lookup Table Channel Mode Address in User RAM of Lookup Table Pin which provides the X (input) value to the Lookup table. May be same as pin being configured 0: No interpolation (Stair step)
1: Linear Interpolation between points
1: RAM

(Other locations such as EEPROM or Flash may be supported in the future).

This message is echoed back by the Wombat.

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.

Data Sent to the Wombat: 201 Pin # 25 Output Enable 0x55 0x55 0x55 0x55
Meaning: Configure Pin Second message Pin Number to be set to 2D Lookup Table Channel Mode 2D Lookup Table Channel Mode 0: Pin retains whatever state it was in prior to table lookup

1: Pin outputs Table Lookup Result as analog/PWM

Unused Unused Unused Unused
This message is echoed back by the Wombat.

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.

Data Sent to the Wombat: 202 Pin # 25 Pin Output 0x55 0x55 0x55 0x55
Meaning: Configure Pin Second message Pin Number to be set to 2D Lookup Table Channel Mode 2D Lookup Table Channel Mode 0: Low
1: High
2: Input / High Z
Unused Unused Unused Unused
Response from the Wombat:
  202 Pin # 25 Pin Output Pin State 0x55 0x55 0x55
Meaning: Configure Pin Second message Pin Number to be set to 2D Lookup Table Channel Mode 2D Lookup Table Channel Mode 0: Low
1: High
2: Input / High Z
Value read back from pin. Useful if pin is configured as input.
0: low
1: high
Unused Unused Unused

Example 1: Changing the range of a servo by remapping through a lookup table

Consider 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.
This value could be used by another pin (say, for example, pin 16) which is configured to position a servo. This will allow the user to position the servo by changing the input voltage on pin 2:

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.


Graph 1: Transfer function used to map 0 to 65535 count input to 16384 to 49151 count output

The table for Graph 1 is quite simple:

X (input) Y (output)
0 16384
65535 49151

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:

X Y
0 49151
65535 16384

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 linear

A 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.

Brightness
(relative)
PWM Percentage
0 0
1 1
2 2
4 4
8 10
16 25
32 80
35 100

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:

Brightness
(Relative)
Brightness % Brightness Count PWM Percentage
(From Graph)
Count
(PWM % * 65535)
0 0 0 0 0
3.5 10 6554 4 2621
7 20 13107 9 5898
10.5 30 19661 14.5 9503
14 40 26214 20.5 13435
17.5 50 32768 28 18350
21 60 39321 36 23592
24.5 70 45875 46 30146
28 80 52428 59 38665
31.5 90 58982 78 51117
35 100 65535 100 65535

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

x y
0 0
6554 2621
13107 5898
19661 9503
26214 13435
32768 18350
39321 23592
45875 30146
52428 38665
58982 51117
65535 65535

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:

x y
0 65535
10000 0
50000 65535
65535 65535

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.

X (input) Y (output)
0 16384
65535 49151

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.