Giter Site home page Giter Site logo

hexbright's People

Contributors

andyseubert avatar dhiltonp avatar dihydro avatar eagleworks avatar emc2cube avatar mcsarge avatar ptesarik avatar soult avatar timothyasp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hexbright's Issues

set_light is not guaranteed to reach end_level in given time

When calling hb.set_light(startLevel,endLevel,duration), the underlying code does not ensure that endLevel is actually reached in the duration specified.

tl;dr version: light level changes should be actual time-based, rather than assumed time and a counter.

This can easily be checked with code that runs a triangle wave, with a 1000ms timer used to toggle between the two:
hb.set_light(0,500,1000);
hb.set_light(500,0,1000);

If the light does not pulse reasonably smoothly (specifically, it ramps up, then flashes bright before ramping back down), this is an indication that the commands did not reach the endLevel desired, while the second sets its startLevel explicitly, thus making it appear to 'flash' bright / dark.
This can become readily apparent just by setting DEBUG = 2 (DEBUG_ON).

The main cause of this problem is in how change_done is treated, but to explain that, I'll backtrack a bit.
set_light() checks the startLevel and endLevel values and sets up the actual time over which the light should change - change_duration - between these two by taking the number of milliseconds specified, and dividing that by update_delay [8.3333333].
The main loop calls adjust_light(), which calls get_max_light_level(), which calls get_light_level() which in turn performs the following pseudomath...
intensity = startIntensity + (intensityDifference) * (percentChangeComplete).
...where percentChangeComplete is calculated as:
change_done / change_duration.

So where and how is change_done - essentially how far along the intensity change process things are - actually calculated? It turns out that this is initialized at 0 in set_light, and is them modified in adjust_light(), specifically as follows:
change_done++;

This, too, may seem reasonable.. every single time adjust_light is called, the change_done is incremented, and eventually it will reach the number set in change_duration, and the process is done. The problem, however, is that this assumes that adjust_light is called exactly at update_delay intervals. I.e. given the above example code:
change_delay = 1000ms / 8.3333333ms = 120
If adjust_light is called every 8.3333333ms, then change_done has to be called 120 times, and it will match the 1000ms:
120 * 8.3333333ms = 1000ms
But if, instead, any code slows that down even just a little, like the debug code, it instead ends up as:
120 * 10ms = 1200ms
Now generally, that's not a big deal. 1 second, 1.2 seconds, it's not something you would generally notice. Except if you use the example above, where after 1000ms as determined by a timer the code is to ramp down again, putting an actual time constraint on the process. Given that each step is supposed to increase lighting as follows:
(500 - 0) / 120 ~= 4.167
And given that in 1000ms, adjust_light getting called every 10ms means there's only 100 steps being performed, the actual intensity at the end of those 1000ms is:
100 * 4.167 = 417.
This is quite a bit less bright than was intended.

When writing programs, this can be partially mitigated - beyond adjusting the timing values to counteract the above effects.
The author can use CURRENT_LEVEL as the start level of any ends-matched sequence programs instead. The desired level may not be reached, but since the start level of the new sequence matches the actual 'end' level of the previous sequence, there's no visual discontinuity.
Alternatively, light_change_remaining() could be used to detect when set_light() is actually done before starting a new sequence. This ensures that the desired level is reached, at the expense of highly variable timing.

In terms of the library, this could be fixed by mapping the change across actual time - e.g. using millis(). The up side of this is that the actual behavior then matches the expected behavior - set_light(0,500,1000) will ramp up the light in 1000ms with an error margin no greater than a single run through the library and user's code, rather than the accumulated effect of a great number of runs. The down side is that this is likely to take up more space; a rather naive implementation (lots of intermediate variables) added 60 bytes. Ouch.

Accelerometer functions

Trying to understand some of this accelerometer stuff in a possible attempt to see if there is any room for improvement. What is the purpose of find_down? All it seems to do is average the last 4 settings... is that just because the accelerometer isn't consider precise and the down vector should be used to filter out noise? Real "down" seems to always be -100 in the 2nd axis... am I missing something?

Modification to the storbe in Tactical program

If the strobe had a bit of jitter, around +- 4 milliseconds, it would be even more disorienting. I had tried to implement this with random(-2,5) but it didn't seem to work quite as well as I hoped.

print_binary.cpp is linked/included unintentionally and bloats program

Anytime ANY file in hb_utilities is referenced the entire folder gets compiled and linked. The linker is pretty good about throwing out what isn't used but I think because eventSerial is referenced in the main.cpp (internal to Arduino) that somehow the Serial stuff sticks in a bad way.

My code:

#include <click_counter.h>

Building:

Global variables use 195 bytes (19%) of dynamic memory,

With that line commented:

Global variables use 22 bytes (2%) of dynamic memory,

Note, I'm not even actually using any click_counter code in this example... the whole difference you are seeing is the extra Serial variable space that's getting added.

I'm not sure of anyway to fix this without putting each of the libraries into separate folders instead of having them all in the same folder. At the very least print_binary should be split off. I can do this and submit a pull request I just wasn't sure what direction I should go with fixing this. Or maybe you have a better idea?

I'm using Arduino 1.5.x but I'd guess the older IDE might exhibit the same behavior.

Getting an Error when Compileing Tactical in Arduino 1.0.6

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
Arduino: 1.0.6 (Windows NT (unknown)), Board: "Hexbright"
tactical:36: error: 'hexbright' does not name a type
tactical:43: error: 'OFF_LEVEL' was not declared in this scope
tactical.ino: In function 'void setup()':
tactical:49: error: 'hb' was not declared in this scope
tactical.ino: In function 'void loop()':
tactical:53: error: 'hb' was not declared in this scope
tactical:69: error: 'CURRENT_LEVEL' was not declared in this scope
tactical:75: error: 'MAX_LEVEL' was not declared in this scope
tactical:80: error: 'print_power' was not declared in this scope

hexbright.cpp fails to compile on ubuntu 12.04.1 "precise"

Wire.h comes from arduino-core 1:1.0+dfsg-9.

hexbright/libraries/hexbright/hexbright.cpp: In static member function 'static void hexbright::read_accelerometer()':
hexbright/libraries/hexbright/hexbright.cpp:634:28: error: call of overloaded 'write(int)' is ambiguous
/usr/share/arduino/libraries/Wire/Wire.h:55:20: note: candidates are: virtual size_t TwoWire::write(uint8_t)
/usr/share/arduino/hardware/arduino/cores/arduino/Print.h:49:12: note:                 size_t Print::write(const char*)
hexbright/libraries/hexbright/hexbright.cpp:635:31: error: no matching function for call to 'TwoWire::endTransmission(int)'
/usr/share/arduino/libraries/Wire/Wire.h:52:13: note: candidate is: uint8_t TwoWire::endTransmission()
hexbright/libraries/hexbright/hexbright.cpp: In static member function 'static unsigned char hexbright::read_accelerometer(unsigned char)':
hexbright/libraries/hexbright/hexbright.cpp:659:31: error: no matching function for call to 'TwoWire::endTransmission(int)'
/usr/share/arduino/libraries/Wire/Wire.h:52:13: note: candidate is: uint8_t TwoWire::endTransmission()

This diff actually gets it to compile, and is enough to make at least tactical.ino actually work on the hexbright...

diff --git a/libraries/hexbright/hexbright.cpp b/libraries/hexbright/hexbright.cpp
index 0e0eee9..f57e084 100755
--- a/libraries/hexbright/hexbright.cpp
+++ b/libraries/hexbright/hexbright.cpp
@@ -631,8 +631,8 @@ void hexbright::read_accelerometer() {
   next_vector();
   while(1) {
     Wire.beginTransmission(ACC_ADDRESS);
-    Wire.write(ACC_REG_XOUT);          // starting with ACC_REG_XOUT,
-    Wire.endTransmission(false);
+    Wire.write(ACC_REG_XOUT, sizeof(ACC_REG_XOUT));          // starting with ACC_REG_XOUT,
+    Wire.endTransmission();
     Wire.requestFrom(ACC_ADDRESS, 4);  // read 4 registers (X,Y,Z), TILT
     for(int i=0; i<4; i++) {
       if (!Wire.available())
@@ -656,7 +656,7 @@ unsigned char hexbright::read_accelerometer(unsigned char acc_reg) {
   if (!digitalReadFast(DPIN_ACC_INT)) {
     Wire.beginTransmission(ACC_ADDRESS);
     Wire.write(acc_reg);
-    Wire.endTransmission(false);       // End, but do not stop!
+    Wire.endTransmission();       // End, but do not stop!
     Wire.requestFrom(ACC_ADDRESS, 1);
     return Wire.read();
   }

Where to locate a complete set of schematics

Hello --

I was hoping that you might point me to a set of schematics for the board. The red light goes on but does not power-up beyond that. Upon visual inspection of the board, I suspect that a component may have been damaged when I was "upgrading" to a larger battery (the battery has same electronic spec, just a bit longer). The components are not damaged due to a reverse polarity issue, but likely when I was cleaning off some residual flux.

Thanks in advance for letting me know.

  • E

Write custom versions of arduino functions?

Arduino's pinMode, (digital/analog)(Read/Write) take up 850 bytes all together.

Writing non-generalized versions for our library could reduce our flash footprint. Investigate costs/benefits.

Hard blink functionality? (Emulating a flakey / bad flashlight)

I've got a project that requires a "flakey flashlight", and remembered my nifty programmable Hexbright.

I thought I was clever trying to use this snippet to make it act like an intermittent connection:

hb.set_light(0, 500, NOW); //Turn on bulb
delay(random(100, 1000)); //leave it on for a bit
hb.set_light(CURRENT_LEVEL, 0, 40);  //let it die
delay(random(1000, 4000)); //leave it off a while

But now I see that the library really doesn't like working with inline delays. I've cribbed your bike strobe code to get me sort of close, but it doesn't let me have that "solid on" effect for a while before starting the decay.

I don't mind beating my head on the code wall to get the effect I'm after, but I sure could use a pointer to what methodology would do the job.

For what it's worth, I've added the successful code I have running so far.
Thx,
Dave
(rename to .ino as Github doesn't seem to like the .ino extension...)
hexbright_slenderman.txt

tap detect

some angle change, little rotation, significant change in direction

drop detect

detect drops (change in velocity, some angle change)

tests:
positive:
drop on grass
drop on floor
drop in bushes

negative:
drop while in bag (no angle change?)
normal? use

spin detect

spinning around long axis, minimal angle,

When integrating some of these, make sure something like tossing the light doesn't activate anything.

unable to make up_n_down work..

Can't seem to make up_n_down work. I flash it to my hexbright and I don't get anything, the taillight lights red when I tap it. That's all I get.. Any ideas?

I should add that I can flash the other programs just fine, they work as intended.

-J

Suggestion: High beam/low beam toggle in BikeLight

Firstly, thank you for making such a fantastic set of code for HexBright, it really-is second to none!

I use my HexBright every day for commuting on my bike.

In my experience it can be quite dazzling for other drivers and I would find it very useful if on my light there was a toggle between high beam and low beam.

Please may I suggest the following change:

Short press after the light is turned on (but not restricted to JUST after it's turned on) results in a toggle between high beam and low beam.

Thanks,

Peter :)

"Text Instructions" incomplete

After step 9, "and select a program"... it would be nice to have instructions on what to actually do with that program. (Ideally, name one that you actually expect to work, and walk through uploading it, and making a one-line change to it and uploading the new one.)

investigate main led timer adjustment

Investigate timer modes as they relate to:

  • reducing the intermittent flickering when changing between high and low modes
  • power consumption changes
  • light intensity changes at a given level

Replace Serial with Debug?

What if we changed...

#ifdef FREE_RAM
  Serial.print("Ram available: ");
  Serial.print(freeRam());
  Serial.println("/1024 bytes");
#endif

to

#ifdef FREE_RAM
  Debug.print("Ram available: ");
  Debug.print(freeRam());
  Debug.println("/1024 bytes");
#endif

A new Debug object could be introduced that checked for charge_state of BATTERY and if the user isn't plugged into USB all the serial statements short-circuit without wasting any time... and if it is plugged in then Serial.whatever runs as it usually would. The call overhead would be nothing compared to the Serial overhead itself.

Would that help?

Intermittent hour-long hangs due to timestamp-overflow

When micros() wraps around (roughly once an hour), hexbright::update() will intermittently hang or resume processing due to "now" wrapping around while "continue_time" is stuck near the high-end. Thankfully the fix is simple, and has been tested by using the modified hexbright library for a few days of continuous operation without issue.

This code:

    do {
      now = micros();
    } while (continue_time > now); // not ready for update

...needs to be changed to:

    do {
      now = micros();
    } while ((signed long)(continue_time - now) > 0); // not ready for update

I hope that helps! :)

Investigate numeric entry options

spin to change number; count button presses?

parity with print_number could be good - use the same delays, led color switching.

Possible issues: we can't do the exact same color scheme (we start red). Using delays to switch positions may be problematic. Perhaps long presses to change digits? Rotate to select the digit, press the button to alter the value?

Suggestion: Two programs at once

Just a suggestion, it would be great if there was a way to load two programs at once, for instance having the Tactical program for day-to-day use and when cycling be able to switch over to the BikeLight program.

Such a change could possibly be done through double-tapping the button when the light is off or holding the button for five seconds?

How feasible is such an idea?

Serial.h: No such file or directory

I am using arduino 1.0.5 installed from Fedora 19 repos. I can see that Serial.h exists in ardunio trunk http://code.google.com/p/arduino/source/browse/trunk/targets/?r=132#targets%2Farduino, but for some reason I don't see it anywhere installed. I also downloaded the arduino software tarballs and didn't see Serial.h in there.

Any assistance to resolving the missing Serial.h is appreciated.

In file included from /home/achasen/sketchbook/hexbright/libraries/hb_utilities/print_binary.cpp:1:0:
/home/achasen/sketchbook/hexbright/libraries/hb_utilities/print_binary.h:5:20: fatal error: Serial.h: No such file or directory

Thanks!

jab detect

optional sensitivity.

minimal rotational movement, minimal angle change, large movement on specific axis

Change structure of library to organize things better

Please hear me out. I'd like to suggest reworking the hexbright library into separate concerns per file. Same class as before, but defined by function, such as:

  • hexbright.h
  • hexbright.cpp
  • power.cpp
  • accel.cpp
  • leds.cpp
  • lighting.cpp
  • buttons.cpp

As far as I can see the only technical issue preventing this is the crazy BUILD_HACK stuff and the idea that .ino files should control how the library compiles (strobe, etc).

Here is what I have in mind to tweak: The library should be compiled as a library, and library configuration should be in hexbright/settings.h. This would hold settings such as which main library features to turn on or off, which light level code to use, etc... it would allow you to easily review and comment all the configuration options without mixing them up with the actual code. hexbright.h would require settings.h, so the settings are available everywhere. hexbright.h would contain the class declaration, the .cpp files would contain all the definitions.

It might mean a few libraries would ALSO require tweaking settings, but I don't think this is the end of the world. I could be documented... or in some of cases it could be avoiding by dealing with a few additional things at run-time. Strobes is currently the biggest example of this behavior I see right now (an optional feature changing the core library).

Dealing with strobes

All update_spin does really is burn CPU cycles for 8333 microseconds (well subtracting out your programs loop cost). Instead of replacing the function wholesale at compile time I suggest we have a function pointer to an idler configurable function. The default would be none and update_spin would look pretty much as it does now. Libraries that required super fine grained control of the hardware could provide their own idler function and it would be called inside the update_spin do/while loop. Of course this would be documented and explain the caveats of using this (timing is critical) - pretty much the same as writing your own update_spin now.

So update_spin would just be responsible for deciding when to start the next "cycle" (as the default does now) and the idler function provided by strobe.cpp would be responsible for cycling the strobe during the idle time of update_spin.

This would add a few bytes for the function pointer and calls, etc... but it shouldn't be significant since we're not really duplicating much (if any) code... idler isn't a full rewrite of update_spin, just the strobe timing/functionality.

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.