Sharp Serial Lookup

0 views
Skip to first unread message

Antonio Brittenham

unread,
Aug 4, 2024, 4:58:06 PM8/4/24
to logeduve
Oneproblem I have with this solution is all of the "Reserved" values. I don't want to create those redundant "reserved" values. Or else I can have an if statement against all of the various places that are "reserved" but they might now be just 2-3, might be 2-3, 40-55 and all different places in the byte. This if statement would get unruly quick

The absolute fastest way to do lookups of integer values in C# is with an array. This will be preferable to using a dictionary, maybe, if you are trying to do tens of thousands of lookups at a time. For most purposes, this is overkill; it's more likely that you need to optimize developer time than processor time.


If the reserved keys are not simply all keys that aren't in the lookup table (i.e. if a lookup for a key can return the found value, a not-found status, or a reserved status), you'll need to save the reserved keys somewhere. Saving them as dictionary entries with magic values (e.g. the key of any dictionary entry whose value is null is reserved) is OK unless you write code that iterates over the dictionary's entries without filtering them.


You'll note that this still has the magic-value issue - Lookup returns null if the key is reserved, and throws an exception if it's not in the table - but at least now you can iterate over Table.Values without filtering magic values.


As far as your "reserved" keys go, I wouldn't worry about that at all if we're only talking about a few hundred keys/values. It's only when you reach tens, maybe hundreds of thousands of "reserved" keys/values that you'll want to implement something more efficient.


I'm not quite sure I understand your problem correctly. You have a collection of strings. Each string is associated to an index. The consumer requests gives an index and you return the corresponding string, unless the index is reserved. Right?


Your question seems to imply that the query key is an integer. Since you have at most 256 items, then the query key is in the range 0..255, right? If so, just have a string array of 256 strings, and use the key as an index into the array.


If your query key is a string value, then it's more like a real lookup table. Using a Dictionary object is simple, but if you're after raw speed for a set of as few as 50 or so actual answers, a do-it-yourself approach such as binary search, or a trie, could be quicker. If you use binary search, since the number of items is so small, you could unroll it.


On the other hand, I assume you've proven that this lookup is your bottleneck, either by profiling or taking stackshots. If less than 10% of time-when-slow is spent in this query, then it is not your bottleneck so you may as well do the thing that is easiest to code.


Hey Guys,

Let me pick your brain for a minute here.

I'm having some trouble getting useful stuff out of this Sharp GP2D120XJ00F.

The datasheet for this thing is here: _SS.pdf

I'm connecting it to an Arduino UNO, and it runs on the 5V power line.

I've got a few questions about this thing.


The simplest way to linearize is to use a lookup table. Declare an array of 256 bytes (say) and for byte 0, store the distance that represents an analog reading of 0 (analogRead() >> 2, so we only look at 256 bytes). For byte 1 of the array, store the distance that represents an analog reading of 1, and so on.


So the lookup table - this poses another problem - how does one get the values to store in this lookup table.

The graph is not quite precise enough, and doing it by hand / experimentation seems a long and arduous process.

I found this info - -projects/arduino-using-a-sharp-ir-sensor-for-distance-calculation/

But I could use some extra background information on the idea, I don't quite understand it enough to modify this to get linear 0 -> 1024 values out of my sensor.


A 33ufd ceramic cap? Are you sure? It's hard to believe you found a non-polarized cap of that size. You have made some kind of error in either the cap you selected or how you wired it up. Caps don't get warm or hot if used properly.


Worked with another sharp distance sensor and wrote the multimap() function just to do that. See - -

it interpolates linear between points of the graph. More points means less error more processing time.


I'll upload a picture of that cap in a bit.

About the multimap - that looks great!

Only problem is, it takes around 300 millis, best case scenario to run the code.

I have to run it twice, and also at least 24 times a second.

So, that solution will not be fast enough.


(from the playground muiltimap article)

Performance

In a small test with an input array of 14 elements, 10.000 worst case calls took 1003 millis, 10.000 best case calls took 358 millis so on average 1361/2 = 680 micros per call. This performance is most affected by the size of the array it has to search, so the general advice is keep the array as small as possible. Note these numbers are only indicative.


If you need max speed the lookupcode proposed by RuggedCircuits in reply #1 is fastest. The # entries in the array can be as low or large (max 1024) as you want but multiples of makes the simplest math. You can even use 2 (or more) lookuparrays - one with bigger steps for the flat part and one with more steps for the dynamic part. You get something like:


The Sharp family of infrared ranging modules These modules are used extensively for robotics and automatic distance measurement applications. Unfortunately, the output of these sensors are inherently non-linear. In other words, a big change in output...


With a little effort, you can get that formula to work entirely with ints (or longs, depending on the kind of resolution you're looking for, but the resolution on those sharp sensors isn't all that great either way) and it'll run very fast.


Here is a sketch that I played around with to try and linearize the IR output. It's been awhile sense I used it so I don't recall my success with it, but it is something that might give you a starting point for further development.


The one jraskell posted (Linearizing Sharp Ranger Data Acroname) is the only one to use if you want to do it right. All Sharp IR-distance sensors function by the way of triangulation and if you do the math, you will end up with a formula distance = const / ( Measurement + offset).


Note that this is an inverse law, not a linear functional relationship. So it is generally not a good idea to use linearized methods for getting distance values out of such a sensor. By the way - for many applications, for example object avoidance, you do not need the distance in cm or inches. You can directly work with the raw measurements.


These Sharp sensors are quite fascinating devices - with two servos, you can even turn them into a slow 3D scanner (see attached image). They easily outperform ultrasound devices in terms of resolution.


One additional (important) note: these Sharp sensors are power hungry. The datasheet mentions a rather low current - but this is only the time averaged current consumption. The peak current these sensors are drawing when they are firing is immense! So in order to get good results, it helps to have a big capacitor close to the IR-sensors power connectors. Be sure to connect it with the right polarity, otherwise, things might get explosive...


Ideally, one pairs this big capacitor with a small capacitor to block high frequency noise as well (Google or any other search engine is certainly your friend here). And be sure to sample the output voltage with the appropriate delay after triggering a measurement...


Hey Guys,

Here's an image of the capacitor, and the way I hooked it up.

(except for the fact that the capacitor I used did not seem to have a polarity)

I'll tinker a bit with the code you provided me with, and will keep you posted.

Thanks,

Jim


Ok, Here's a little update.

Got me some new capacitors, hooked up a big one and a small one (for HF filtering) and this seems to work.

I used the formulas found here - Linearizing Sharp Ranger Data Acroname.

I more or less wrapped my head around the theory.

But, when I use the "R = (2914 / (V + 5)) - 1" as proposed at the end of the page, I get almost perfect distance readings in cm.

I would like to have them as a value from 0 - 254 though, but since I'm using floating point values, I don't think the map function is working out quite right.

Here's my code.


As the reference mentions in the appendix, the library version is working with longs; if you want to use your floats, either do an explict cast to long, or, even better, simply implement the formula given in the appendix yourself, with floats. Here's one possibility:


As for your capacitor - this is indeed a tantal one, and it has a polarity. Sometimes, there's a really tiny dot or "plus" on one of the legs, sometimes a single leg is slightly longer bend away from the main body of the capacitor. That's the plus pole....


Hey Guys,

Here's my code.

The analog reads from inputs 0 and 1 are the IR rangers.

At the top of the range I get severe jitter though.

Are they just that imprecise, or is it a problem in my code?

Like suggested, I connected the rangers to capacitors to stabilize the voltage.

Also, I take many readings and average them out. Should that not make them more stable?

So - any suggestions?


Actually, the measurements of a Sharp IR distance sensor are quite stable over time. If you notice jitter in the readings, it is most probably caused by a not sufficiently stable power supply. As I already remarked, these device draw a lot of current when they are firing. Be sure to have sufficient and good capacitors as close to the sensor as possible (ideally a big one for the large power spike, plus a 10nF one in parallel for the high-frequency components).


One the other hand, due to the principle these sensors work with (triangulation), they have a much greater resolution at short distances than on distances farther away. Very similar to human 3D vision which works best at close distances. Any noise you have in the system is basically magnified (distance-wise) if you are working at the upper edge of the distance range.

3a8082e126
Reply all
Reply to author
Forward
0 new messages