Show Posts
Pages: [1]
1  Using Arduino / Programming Questions / Re: Bug? Multiple class instances - Static variables overwriting each other on: June 27, 2013, 07:40:00 am
Quote
The normal meaning of static operates like a private variable store per function. It's static, persistent, and only accessible to that function. That same functionality is what I hoped for in the classes too. If I wanted it shared, I'd have specifically linked pointers to data stores between them, but it seems the language seems to do that for you, with no option of choosing the interpretation.

Ah, there is only one copy of the code of a class there are many copies of the data! Static means one copy only not one per instance.

Mark

Seems I got to become intimately familliar with the intricacies of this ;p

I solved it by creating a data subclass to hold the variables for each mode, which only needed minimal code changes to each mode. existingVar to f.existingVar. It's clunky, but the lights are all happily following their own paths now, as intended by it's creator.
2  Using Arduino / Programming Questions / Re: Bug? Multiple class instances - Static variables overwriting each other on: June 27, 2013, 07:03:27 am

Will need a complete rewrite of the class, top to bottom if wanting to use multiple instances. I'm sad smiley-sad

Each LED has about 5 operating modes, and each mode usually has about 10-15 static variables/defaults to track fade amounts, timing, synch, brightness calculations and stuff, depending on if it's a fade, pulse, jump, or synched to a song bpm set. Also so each mode keeps it's last state/setting data when a new mode is active. Dumping all that in the class scope will feel horrible.

Well you can't have your cake and eat it too. You are complaining that the variables are shared, and then saying you want them to be shared.

If I thought that, then that would indeed be silly, which of course I don't ;p

I also didin't mention anything about wanting the variables to be shared, I don't. I want only the relevent mode's member function to have access to it, no other function, and no other instance. Every instance is responsible for it's own LED & various modes, and nothing else.

The normal meaning of static operates like a private variable store per function. It's static, persistent, and only accessible to that function. That same functionality is what I hoped for in the classes too. If I wanted it shared, I'd have specifically linked pointers to data stores between them, but it seems the language seems to do that for you, with no option of choosing the interpretation.

Anyway, seems I need to bite the bullet and rewrite. Thanks anyway. smiley
3  Using Arduino / Programming Questions / Re: Bug? Multiple class instances - Static variables overwriting each other on: June 27, 2013, 05:45:39 am
Really? o_o Ack, that's frustrating. It seems rather unclean to have it's accepted functionality be changed depending where it's used.

Will need a complete rewrite of the class, top to bottom if wanting to use multiple instances. I'm sad smiley-sad

Each LED has about 5 operating modes, and each mode usually has about 10-15 static variables/defaults to track fade amounts, timing, synch, brightness calculations and stuff, depending on if it's a fade, pulse, jump, or synched to a song bpm set. Also so each mode keeps it's last state/setting data when a new mode is active. Dumping all that in the class scope will feel horrible. Might try a shared struct array between modes instead, each mode accessing the array index corresponding to the instance ID of the class.

Ick.

@ holmes4: You're right, though I was inclined to direct some animosity towards the new operator as implemented in the arduino. Little chance of finding a bug in C/C++ it's self these days, barring compiler quirks ;p
4  Using Arduino / Programming Questions / Bug? Multiple class instances - Static variables overwriting each other on: June 27, 2013, 04:40:16 am
I've run up against a very peculiar problem, replicated with test code. When upgrading my project from single to multiple LED channel control (via creating instances of the LED control class I created), I noticed both LED channels were selecting the -exact- same random colour to fade between, every time, without fail.

what I discovered, is that:

- when instance 0 chose a new colour, instance 1 would be expected to immediately choose a new one too, but it acts as if it already picked a colour, and begins following the identical colour of the first instance. This should be impossible, because the members in each class have their own private static variables which stores the led state data.

I replicated the problem with test code. Sorry for the length! It's as short as I can get it, while still replicating the programming style used. My gut feeling is a bug with the 'new' operator.

P.S. Defensive disclaimer: I'm not the best programmer of frameworks/structures in the world, but it works ;p I know there's a million and one moral crusades with regards to how certain things should be done, but in this case I'm working under the assumption the designers wouldn't leave broken features available if they knew they didn't work as intended. this is a stable release after all, perish the thought.

Tested under V1.0.3, V1.0.5, same issues.

Win 7, Arduino Mega 2560 Rev3

Code:
#include <Arduino.h>

class randomInstance {

  public:
    uint8_t id;
    
    randomInstance         (uint8_t instanceNum);
    void memberWithStatics (bool showVars = false);
};

randomInstance::randomInstance(uint8_t instanceNum){
  this->id = instanceNum;    
  this->memberWithStatics(); //Initialize the members with a first-run of colour selection.
};

void randomInstance::memberWithStatics(bool showVars){
  static uint32_t lastExecute = millis(), ticks=0;
  static uint32_t colour      = random(0x0, 0xFFFFFF);
  static uint32_t lastColour  = 0;
  
  if(showVars){
    Serial.print(F("memberWithStatics: lastColour ")); Serial.print(lastColour, HEX);
    Serial.print(F(" colour: "));      Serial.print(colour, HEX);
    Serial.print(F(" ticks: "));       Serial.print(ticks);
    Serial.print(F(" lastExecute: ")); Serial.print(lastExecute);
    Serial.print(F(" instanceID "));   Serial.println(this->id);
    return;
  };
  
  //If user didin't want variables dumped, assign new variables to everything
  lastColour  = colour;
  colour      = random(0x0, 0xFFFFFF);
  lastExecute = millis();
  ticks++;
};




randomInstance *instances[2]; //Pointer array for our class instances.

void setup(){
  Serial.begin(115200);
  
  //Allocate & initialize our instances
  instances[0] = new randomInstance(0);
  instances[1] = new randomInstance(1);
  
};

void loop(){
  Serial.println(F("Main: Dumping current data: "));
  instances[0]->memberWithStatics(true);
  instances[1]->memberWithStatics(true);  
  
  //Make instance 0 pick a new colour
  instances[0]->memberWithStatics();

  Serial.println(F("\nMain: Instance 0 called, new dump: "));
  instances[0]->memberWithStatics(true);
  instances[1]->memberWithStatics(true);  

  //Make instance 1 pick a new colour
  instances[1]->memberWithStatics();

  Serial.println(F("\nMain: Instance 1 called, new dump: "));
  instances[0]->memberWithStatics(true);
  instances[1]->memberWithStatics(true);  
  
  delay(10000);
};

Output:
Code:
Main: Dumping current data:
memberWithStatics: lastColour 6DAE4 colour: 58EDE ticks: 2 lastExecute: 1 instanceID 0
memberWithStatics: lastColour 6DAE4 colour: 58EDE ticks: 2 lastExecute: 1 instanceID 1

Main: Instance 0 called, new dump:
memberWithStatics: lastColour 58EDE colour: E50A54 ticks: 3 lastExecute: 12 instanceID 0
memberWithStatics: lastColour 58EDE colour: E50A54 ticks: 3 lastExecute: 12 instanceID 1

Main: Instance 1 called, new dump:
memberWithStatics: lastColour E50A54 colour: F32F99 ticks: 4 lastExecute: 30 instanceID 0
memberWithStatics: lastColour E50A54 colour: F32F99 ticks: 4 lastExecute: 30 instanceID 1
5  Using Arduino / Project Guidance / Re: Using finger hall sensors to control Arduino & leds. Has it been done? on: May 12, 2013, 02:36:12 pm
@ Erdin: Thanks for the info, especially on the Pro Mini & 12 port Leonardo, that might just be what I'm looking for! You're right about the hall sensor above the fingernail, these are sensitive enough for a~13-20cm detection distance, dependng on the magnet strength (or further with analog port oversampling). I just ordered some magnetic fridge-tape, I'm hoping the flexibility and magnetic strength is significant enough to pick up. Otherwise the coil idea may work better.

I just checked the project box I bought to house the pcb & arduino, a mega would need one of the screw risers to be chopped off to fit, but can work if push comes to shove.

The wire I'll be using is just some 1mm stranded copper. I'll try figure out an efficient gnd/+5v routing plan so there's not too many wires going along my arm.

As for hall sensors, you both raise good points, I have a handful of A1302 analog ratiometric sensors, so I can make a calibration routine to determine initial tolerances for each sensor, to help prevent false positives/negitives and such.

And interesting project there by the way, mike!
6  Using Arduino / Project Guidance / Re: Using finger hall sensors to control Arduino & leds. Has it been done? on: May 12, 2013, 07:00:03 am
Thanks for the link Erdin, though the lmgtfy link really wasn't necessary ;p

I was referring to having already tried various google search terms for completed low-profile projects and libraries, rather than available research/theory. The Ardu forum search was offline.

Most of the available projects out there seem to rely on USB or are very bulky. I'm hoping for one built into thin spandex gloves, for example.

Edit, there's one interesting project funded two years ago: http://www.kickstarter.com/projects/jrowberg/keyglove-wearable-input-device - Seems to rely on electrical contact than hall sensors (which can't be worn under another glove)



Indeed, the programming won't be too hard, I'll manage it fine. Lots of testing and debugging. smiley-sad  Looks like it's time to cook up a new library.

Seems I'll need an ardu mega too, for the 8 analog inputs.

7  Using Arduino / Project Guidance / Using finger hall sensors to control Arduino & leds. Has it been done? on: May 12, 2013, 04:17:58 am
Hey all smiley

In an effort to avoid unnecessarily reinventing the wheel, are there any projects out there which use hall sensors & magnetic strip attached to a glove to communicate with the arduino?

Tried a google search for various terms, but sadly the search function on here is sadly offline.

- How it works:
I'm planning to use 4 hall sensors per hand, with a magnetic strip attached to the palm.

The right hand are the 'option groups'
The left hand sets the value for that group. To switch all leds to strobe for example, you hold finger 3 of the right hand against your palm (R3), then hold finger 3 (L3) of your left palm. To quickly restore to default, hold R3 then all left fingers (L*).

R1 = Colour control
  L1/L2/L3/L4/L* = Red, green, blue, white, all-fingers = default colour mixes.
R2 = Speed/fade control
 L1/L2/L3 = slow, medium, fast
R3 = Mode
 L1/L2/L3/L4/L* = torch, multi-fade, strobe, flash, reset to default
R4 = reserved

I'd appreciate any links or hints to existing projects and stuff. If not, time to get soldering and coding!
8  Using Arduino / Programming Questions / Re: [Solved] Best practices for debugging memory corruption and free() woes? on: January 31, 2013, 07:33:02 am
Hmmm, this is good food for thought, those are some interesting tips and pitfalls you both present. I suppose my approach would begin to encounter unexpected problems like these as the program codebase grows, objects get larger and allocations get more frequent and varied.

Looks like I'll need to brush up my c++ foo to figure out some rudimentary garbage collecting/compacting, smart pointers and cooking up some new/delete methods  smiley-eek

Thanks for the tips ;p
9  Using Arduino / Programming Questions / Re: Best practices for debugging memory corruption and free() woes? on: January 31, 2013, 05:22:45 am
An interesting take on uC memory management  smiley-razz

I do think it has it's pros and cons, but I feel the benefits can outweigh some of the risks, provided malloc/free works as advertised, and you take care to avoid thrashing the free list ;p

I'm probably looking at this from a wholly different angle, but thrifty malloc/free memory management on a microcontroller makes even more sense to me on these types of platforms, especially if your codebase on the platform has many logic branches, states and data structures. It feels cleaner to allocate only the memory those particular branches of logic need at any particular state in the program.

For example, in a state-based methodology, if your code has a setup state where it's verifying all the sensors, calibrating base levels, monitoring for interference and performing serial init routines on all connected devices; there's the potential to need some types of data and structures that will no longer be relevant for the rest of that programs lifecycle, it would make sense to free all that up, since repurposing/recasting the same batch of memory from a structure, to a string array for example, could makes things less flexible for you. Concurrency also becomes a dangerous and complicated minefield, if all your functions are all vying for the same fixed blocks of memory. You'd need to be careful for functions calling functions, and keeping very close track of what fixed blocks each of those functions are going to be using.

Chances are there will be many situations where you're storing a cardboard box in a 90% empty part of the room, and since you aren't allowed to use room dividers to store other things in that same room, things just got more complicated for you, with the need for some homegrown code needed to manually manage all your space. Or (if the core functions were implemented right, and were efficient in re-integrating smaller unused blocks back into superblocks), you can use decades-old, time-tested methods and functions to manage that for you ;p


2-8kb of memory feels like a precious resource to be used on a strictly as-needed basis smiley
10  Using Arduino / Programming Questions / Re: Best practices for debugging memory corruption and free() woes? on: January 30, 2013, 11:40:21 am
Thanks for the responses!  smiley

There's a bug in free. Read about it here: http://code.google.com/p/arduino/issues/detail?id=857.

I do wonder though whether the seemingly unrelated piece of code isn't quite as unrelated as it appears.

I was hoping that particular issue wasn't applicable to me... but it looks like it was the case!

You would be quite right to wonder about the 'unrelated code'  smiley-razz I checked over the code another 10 times, headscratched a similar number of times, then implemented the patch to the ardu core for malloc/free here: http://arduino.cc/forum/index.php/topic,95914.msg1036128.html#msg1036128


So far, I am no longer able to reproduce the free() misbehavior with the same branch of logic and combination of print statements as before. Previously I tried ide 1.0.1 and 1.0.3 with the same problems.

Though I'm now curious why an IDE at a production level of release, has an almost year-old core bug, which has likely contributed to the general advice to avoid sometimes really-useful general memory management abilities for an entire prototyping platform  smiley-eek-blue
11  Using Arduino / Programming Questions / [Solved] Best practices for debugging memory corruption and free() woes? on: January 30, 2013, 10:24:22 am
Hello all! I've been a long time silent admirer of the sheer amount of libraries and knowledge out there, and I must humbly break that silence with a request for debugging tips!

I've read the musings of 'dark side'  smiley-lol microcontroller programming with malloc() and free(), and all their pitfalls such as fragmentation, out of memory conditions and rumours of print() and println() shenanigans. The issue I've encountered isn't really corruption, but free() doing some odd things like magically freeing 100-400 bytes of data from a malloc'ed pointer of 2 bytes.


I've been working on a program that speaks with a serial device via Serial1, and the console on Serial, and created an event queue system which executes a task when due (checking for heartbeat, send a timed command to the device, request the state of a control, etc)

An events lifecycle follows this process:

1: call eventQueue->addEvent(time, function pointer, a small byte* array)
  We've now saved the time, a function pointer and byte pointer.

2: call eventQueue->checkExpire();
  1: When an event is due to be run, we call the function pointer, and hand it the packet of data
  2: The function may re-add it's self with a new time and new packet of data
  3: We free() the old packet of data and destroy the event.

There are two events in our queue, each with a 2 byte data packet, firing rapidly at 10-100 times a second, and all seems to go well. The little byte arrays have pointers that cycle through 0xf70, 0xf74, 0xf78 and then back to 0xf70, so fragmentation doesn't seem to be a worry. (if I remember right, each pointer created with malloc() has a 2 byte header array to help free() know how to handle it)

Our free memory hovers at 4694 bytes, give or take 4 bytes depending on when we measured it. Here is how the queue normally chugs along:

Code:
eq->checkExpire:  Calling function 0x210C with data pkt 0xF70
 eq->addEvent: func 0x210C pkt 0xF74
 pop: free() ptr: 0xF70 mem before: 4694 mem after: 4698

eq->checkExpire:  Calling function 0x210C with data pkt 0xF74
 eq->addEvent: func 0x210C pkt 0xF78
 pop: free() ptr: 0xF74 mem before: 4694 mem after: 4698

eq->checkExpire:  Calling function 0x210C with data pkt 0xF78
 eq->addEvent: func 0x210C pkt 0xF70
 pop: free() ptr: 0xF78 mem before: 4694 mem after: 4698

.. and so on.

However, here's the part that has taken a day of debugging to narrow down! When a "seemingly-unrelated" piece of logic alters a variable in an independent, fixed data structure, things take a sour turn very quickly. As you can see, our event system measures the memory in use immediatley before, and immediatley after freeing the data packet. We expect to regain 4 bytes, but we suddenly start seeing huge chunks of 200-400b 'freed' memory, from a 2 byte pointer.

Code:
readSensors: Processed input from Sensor 5

eq->checkExpire:  Calling function 0x210C with data pkt 0xF70
 eq->addEvent: func 0x210C pkt 0xF74
 pop: free() ptr: 0xF70 mem before: 4694b mem after: 5160

checkMemory: ***HALT*** MEMORY CORRUPTION: More free memory than after setup() finished:
                       5160b avail, setup(): 4680b


Before I coded the checkMemory function to watch out for this, these events would run on and on, and every free request would blow up another 100-400 bytes of memory, till we show ridiculous free memory sizes like 16kb (on a mega, with a program consuming 42kb of it's flash memory!). After that we'd crash or lock up when malloc() starts returning bogus pointers and generally throwing hissy fits.


So my humble question is, what are some debugging tips you could recommend for tracking down the source of free() misbehaving so badly, as well as general memory corruption? (I didn't include any code here, because this issue has defeated my somewhat-passable debug-fu, and need to improve!  smiley)


P.S.: The check memory function permanently allocates 2 512 byte blocks of memory, at the start of setup() and at the end. They are initialized to 0x1 and the sum of bytes are totaled up once every few main loops in the program, so their sum must always equal the number of bytes, and annoyingly there has been NO observed corruption of these bytes! Just free() being very rebellious.



Specs:
Arduino Mega 2560, 42kb used flash memory.
Serial0 via USB, Serial1 via pins 18/19
Copious amounts of print(), println() and __FlashStringHelper
Arduino IDE  1.0.3
Pages: [1]