Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Delta-Wye
Sep 29, 2005
Rebuild your Arduino projects using a bare atmega chip. You know it can handle the task, so see how much more efficient you can make it. Faster, more robust, more feature-filled, more power efficient, whatever you'd like. There are plenty of reasons to use an Arduino (it certainly makes rapid prototyping easier if you just want to try something out) but "I don't know any other way" is a pretty bad reason to do anything. If you've got the time, rebuilding without the bootloader or Arduino libraries will teach you a lot.

Adbot
ADBOT LOVES YOU

Delta-Wye
Sep 29, 2005
Here is a weird question that I thought someone here may have some insight off the top of their head. When I'm doing embedded programming (say, MSP430) I usually use the smallest datatype available. If I know a value will fit into a char, I'll use a char, even if I am not particularly memory constrained. That is to say I don't just hold ASCII characters in a char datatype, but use it as a 8-bit integer. Supposedly this doesn't work very well on a platform like the MSP430. I was told that the 16-bit processors will read a 16-bit value out of memory, mask it to an 8 bit value, do the required operation, then have to mask it again with the contents of memory when storing it. Needless to say, such masking operations would add computational overhead so if you are not memory constrained it is more computationally efficient to use a 16-bit (int) value.

I haven't taken the time to dig up documentation that specifies one way or the other, or compile c code to assembly and see what it is doing, but am interested if anyone has insight. If it adds a ton of overhead, this would be a counterproductive habit I should break because I am rarely that memory constrained. For cases like a massive array of 8-bit samples or something, the computational overhead may be acceptable, but otherwise I've been doing a very silly thing.

Delta-Wye
Sep 29, 2005

Otto Skorzeny posted:

On any given platform, loads, stores and integer operations will be fastest on datatypes that have the same width as the machine word. Some architectures provide explicit instructions for loading, storing and operating on half words or bytes or whatever, either for convenience or for speed. I wouldn't bother worrying about this until you found some bit of code you're working on where you need to perform X operations in Y ms but are currently taking 2Y ms and the generated assembly looked like it was wasting time marshalling and demarshalling bytes into 16-bit words or whatever. You're much more likely to be wasting time doing something like blocking on a slow peripheral or polling vs waiting for an interrupt anyways, at least in the code I've worked on.

The operations in question were quick interrupt routines on a battery powered MSP430 sensor. A few extra instructions in the work loop could take away weeks of runtime. In theory anyway. It was a homework assignment at the time so we took note of the expected runtime based on the code as is and I didn't look into it further.

Delta-Wye
Sep 29, 2005

Martytoof posted:

Vague question: Is there any MCU with an on-package accelerometer?

I mean a single chip solution, not a development board. I can obviously just add a separate accelerometer to my project but I'm just curious if this thing exists.

I've never seen such a thing, and to be honest, I'd be surprised if it was common place at the moment. As far as I know, MEMS hardware takes special manufacturing processes than typical ICs and combining the two with a complicated MCU design would be a feat. That said, I am seeing more tightly coupled IMU chips lately (https://www.sparkfun.com/products/11028, which includes some amount of onboard processing) and a SoC with a builtin IMU isn't a terrible idea on the surface.

Delta-Wye
Sep 29, 2005

Kire posted:

I'm trying to use my beaglebone, but I'm running in to trouble just trying to install emacs. I've been following this tutorial:
http://www.gigamegablog.com/2012/01/29/beaglebone-linux-101-configuring-angstrom-linux/

and I'm trying to use "wget https://www.angstrom-distribution.org/feeds/2011.03/ipk/glibc/armv7a/base/emacs_22.3-r1.6_armv7a.ipk" but linux keeps telling me "wget: bad address 'www.angstrom-distribution.org'" and since I can't ping any IP addresses from the command line I assume my beaglebone isn't accessing the internet properly? The funny thing is that opkg update and opkg upgrade seemed to work just fine which I believe require accessing the internet. What am I doing wrong?

Edit: Separate question, is there a C/C++ library that would let me do things like "pinMode(usr_LED0, output);" so that I don't have to use Java/Python/Cloud9, but could still control the IO pins really easily?

Edit: vvvvvvvv no luck, quotes didn't help.

If the beaglebone is like other embedded linux systems I've used, there should be gpio entries under /sys/class/gpio and you can modify them with any language capable of opening and writing to a file including commandline tools like echo or cat, along with bash, C, whatever.

EDIT: Google says yes http://beaglebone.cameon.net/home/using-the-gpios I like just doing simple bash scripting, but you ought to be able to knock out a simple C++ library to hide most of the file i/o stuff.

Delta-Wye
Sep 29, 2005

evensevenone posted:

Is there a good general book on embedded programming design patterns? I feel like I always do things certain ways that are probably sub-optimal, at least compared to what smarter people come up with. I read libraries but a lot of the time they are either crap or else super duper arcane and tough to learn from. I feel like there's also a lot of little tricks that I just don't know and wouldn't figure out on my own or by reading code.

Probably something focused more towards smaller micros and bare-metal stuff. Not so interested in embedded OSes right now.

I guess some the big topic I would like are developing rock-solid serial drivers and protocols. But there's probably a whole bunch of other stuff.

I feel that way all the time so I'm always looking for books and tutorials for new approaches to common design problems. I just bought a copy of this: http://www.amazon.com/Practical-UML-Statecharts-Second-Event-Driven/dp/0750687061

Coworker used a few techniques from this book and it looked useful enough to pick up. Gotta step my game up, this approach seems a lot more extendable and easier to document than my hacked together approaches previously.

Delta-Wye
Sep 29, 2005

evensevenone posted:

Funny, that's on my amazon wishlist along with this: http://www.amazon.com/Making-Embedded-Systems-Patterns-Software/dp/1449302149/ref=wl_mb_hu_m_2_dp

I never know with O'Reilly books tough. Some are awesome and some are total duds.

The statechart book arrived a few days ago so whenever I finish Effective C++ I will start on it and let you know if its any good. The O'Reilly book looks good and is on my list now too. Too much stuff to do, not nearly enough time to do it in :(

Delta-Wye
Sep 29, 2005

Cancelbot posted:

This looks too good to be true to me:
http://www.sainsmart.com/new-nxp-arm-cortex-m3-lpc1768-development-board-3-2-tft-lcd-module-64kb-sram.html

As does this (less so)
http://www.sainsmart.com/arduino-co...-atmega8u2.html

Is it sme sort of scam? I'm after a small CPU/display combo to toy around with and most kits seem vastly more expensive.

quote:

Land Tiger development board supporting a wealth of routine and detailed information for users to quickly project development.
Cheap chinese knockoff dev boards - you get what you pay for, but they will probably be, at worst, minimally functional if you just want to dick around with them. Chances are they will work fine, when they show up - free shipping from china is often :lol: slow. That said, you are not going to be able to beat that price locally, assuming you are in NA or Europe.

Delta-Wye
Sep 29, 2005

Rocko Bonaparte posted:

This isn't about embedded programming per-se, but I have a question about analog-digital converters for regular PCs. Specifically, what are some good ones out there? I see a few and can't really make up my mind. I was hoping to find something in the short term that takes a signal from the range of 0-5V, samples it very rapidly, like > 10Hz, and has > 8bit precision. Has anybody worked with anything like this before for situations like this?

A bus pirate can also take ADC readings much faster than 10Hz and stream them over the serial port to the PC. It's overkill for just this, but not a bad idea if you think you could reuse the tool later.

Delta-Wye
Sep 29, 2005

Rocko Bonaparte posted:

This seemed as good a place as any here to ask about some control systems stuff, since that's a common enough reason to use a microcontroller.
I'm sorry if there's a better place for it, but I didn't get anything at all on SA searching for "impulse response" or "transfer function."

I'm trying to figure out how I might model a discrete system for doing some testing. Particularly, it's a thermal environment where I have a quiescent temperature that things would stay at if not adjusted, and a controller that needs a little help hitting a temperature. If I set my controller to that quiescent temperature, it's as if nothing is happening. So I just assume that as my zero point. I was seeing some odd behavior that I don't model, so I was thinking instead it was time to get an impulse response. I just figured if I soaked at the quiescent temperature and then shot up the controller uncompensated for, say, half of a sampling period, I'd get a rough impulse response.

It's been years since I did any of this in school and the professor seemed to know a lot, but most of it didn't really stick. So I know the terms, but I didn't really get all the techniques down and I've long lost all the mathematical muster. I'm trying to figure out how I might model the system based on it's measured discrete impulse response. Then I'm wondering if I could relatively safely apply this to other temperatures, or if I'm just asking for serious trouble trying.

Do you have a closed feedback loop? Can the microcontroller actively read the temperature and compensate? It might help to know what your input/output is (how are you controlling the temperature, for instance).

I was talking with my controls prof (pretty famous old-rear end engineer with tons of experience) about how to model something like a quadcopter (the project I was poking at the time) and he kind of looked at me like I was stupid. In class, we work with equations - you get an equation, and you apply whatever technique we were covering that class to said equations. We didn't really cover where these loving equations come from, they were just provided. Clearly they are describing the behavior of the system, and you can work out why this is proportional to that, etc, but with a complicated system? Meh! Anyways, he looked at me like I was stupid and said he had no idea how you would model one and didn't care to find out, but he had seen youtube videos of kids tuning PID loops to control theirs and he was confident I could figure it out without modeling. "Confident I could figure it out" was said with a great deal of disdain - I did say he was an old rear end engineer, right? :v:

What I'm trying to say is sometimes you don't really need to know anything, you just slap in a generic PID loop and tune your coefficients. Without knowing much about the system, I would guess that would solve it but you would need closed-loop feedback, at least, for that to be a doable approach.

Delta-Wye
Sep 29, 2005

Rocko Bonaparte posted:

I still am hoping to get a model of the system so I can run automatic tests against it. That is my main issue right now. Some of the units I'm using have less consistent behavior. They'll overshoot, but only if they've been jerked around certain ways. It's too complicated for me to derive just by looking at it.

What kind of system are you using that a PID loop can't correct for? It sounds more like a terrible implementation when you tried it than a poor fit to your problem. It's usually not terribly difficult to control overshoot by tuning your gains.

Delta-Wye
Sep 29, 2005

Rocko Bonaparte posted:

I have to deal with different models of thermal controls installed in various different ways. Furthermore, the controllers are moderating different items, and those items can change their behavior at any point in operation. I have to expect to go from any temperature to another temperature within the range of, say, -30C to 100C. When I tried to tune a PID one day, I got it to go from one temperature to another fine enough. A day later, they had to change the environment, including how it was seating, and that PID developed a steady-state error.

Everybody is obsessing over the PID. That's not the thing. Whatever I come up with, I'd like to be able to test across a variety of different models that have given me problems in the past. I'm currently dealing with one with some very odd behavior so the convergence time is longer than I consider acceptable. I do still converge. So I'd like to be able to reproduce it's behavior in a simulation since I can't perpetually sit in front of the gear. Later I want to be able to run regressions against that to make sure I can still handle it. So I'm trying to construct a model of it. That is my preoccupation.

What the gently caress are you building? Christ you are cryptic. :psyduck: I can't help you model "different models of thermal controls installed in various different ways."

We're fixated on a PID as a solution because it is a generic one-size-fits-all approach to control problems - there are certainly better approaches available for certain situations (sliding mode control and a few other approaches I've seen work miracles) but they require more information specifying the system. Literally all we have to go on is "I have a system with a control output and a control feedback sensor, how can I make it stable?" Of course we're going to be talking about a generic PID approach - it's a good match for your generic problem!

Delta-Wye
Sep 29, 2005

mnd posted:

I am not current on AVR stuff, so there may be something better or newer, but for a programmer, I think you want an AVR Dragon.

I've used a dragon and it is fine. They do seem to have a tendency to blow up though, I've had to (and had some enterprising students have to) replace parts on one when it kept smoking things. Admittedly, it was being used by students while I wasn't around to supervise so who knows what happened to it, but ideally a dev tool should be protected against most stupid-developer tricks. God knows I've done enough miswiring or accidental shorting during late-night rush jobs to realize it is inevitable something gets plugged in wrong.

Delta-Wye
Sep 29, 2005
So... "please buy our IMU, oh and no, we won't give you the IMU software to make it work"?

Delta-Wye
Sep 29, 2005
Arduino is for people who are too lazy to read an Atmel datasheet. Of course, when they go to do 30-45 analog reads in a row (the multiplexor guide said it would work!!!!!) and find out that it's hellishly slow they lack both the ability to recognize the problem (ADC reads take a long time) or the solution (kick them off and use an ISR to grab the data instead of spinlocking and waiting). Who guessed learning how to do something complicated would be complicated? :ohdear:

Delta-Wye
Sep 29, 2005

Kire posted:

That's what I thought. So Delta-Wye is saying that the ISRs should read the ADC output when it's ready at the ADC and then return it, rather than having the main thread poll it? I believe this assumes that the hardware supports activating an interrupt flag when the ADC output is ready?

So lets say arduino's backend wrote the AnalogRead() function this way (in psuedocode, I'm not familiar with how the avr compilers want some of this stuff specified)
code:
//no idea for arduino
#define NUM_ANALOG 10

int analogBuffer[NUM_ANALOG]

int analogRead(int channel) {
	return analogBuffer[channel];
}

void ADCISR <interrupt> {
	analogBuffer[0] = ADCREG0;
...
...
	analogBuffer[X] = ADCREGX; 
}
Some platforms need slightly different setups, but you get the idea. Your loop() would do something like this:

code:
int value = analogRead(A0);
serial.println(value);
it will grab the newest value extremely fast and return it. If you are worried about stale data for some reason, let's say you are reading a MUX and you need to know the ADC returned a fresh value since the last address change, you can add a flag that can be checked with very little overhead. If you prefer the old behavior, you would simply do:

code:
while (!analogNewData(A0));
int value = analogRead(A0);
Boom, analogRead() is fixed. Well, 'fixed'. If you're doing a mux and you want to read it as fast as possible, you need to be able to set the address bits in the ISR so each read can be routed to an array, etc etc etc. Sure, it can be done in Arduino, but at 100x the cost in time. I am all for stuff like artists using it, often times it's plenty of horsepower and it's means to an end. If you are building electronics though? Seems like it would be worth cracking the datasheet open. Stuff like digitalRead is trivial to do with memory mapped IO.

Delta-Wye
Sep 29, 2005

JawnV6 posted:

One of these is The Right Way

Books are for dorks :colbert:

Delta-Wye
Sep 29, 2005
Is there any particular reason you're doing c++? The runtime overhead for most of the novel c++ features (polymorphism et al) make it an unusual choice for resource constrained systems like 8bit avr/pic/etc chips.

You can get the benefits of classes in C with structs and making your own *this pointers as an argument to each 'member' function (it's all c++ is doing anyways).

Hell, you can even do inheritance if you really really want to via structs.

Delta-Wye
Sep 29, 2005

Sinestro posted:

How do I learn to layout real PCBs.

"Real" PCBs? If you just mean a normal PCB, I would get a copy of Eagle and follow some tutorials to get started. Once you figure out the software start making lots of circuit boards as they are going to suck at first; like a lot of things, it takes practice.

Base Emitter posted:

Just scoping functions to a class is an ok reason to use C++, that's pretty much what I did for mbed programming. It's handy for modularizing IO that you can instantiate multiple times on different pins, for example, and more convenient than how you'd do it in C with no more overhead.

The one advantage C++ has over other OOP languages is constructing static and stack objects so you don't have to use the heap at all, which is great all by itself for embedded.

Plus, there's so many random BS features in C++ that you should never feel bad ignoring most of the language if a tiny subset solves your problem.

Tell me again about how developing for ARM is fundamentally different than an 8bit micro :allears:

Eh, mostly just giving you a hard time. Curious what exactly you mean by "scoping functions". Are you referring to public/private or seperation? I'm pretty sure you can recreate that by encapsulating a function inside of a library that is a separate .c/.h file by simply not exporting the private functions in the header file.

Delta-Wye fucked around with this message at 13:46 on May 15, 2013

Delta-Wye
Sep 29, 2005

Sinestro posted:

Sorry, I am not at my most coherent at 2:27 AM. I want to learn to do advanced layout, such as a board using a CC430 family chip --I've never payed out a board with wireless on it.

The CC430 chip (only?) comes in a pretty hard to use QFN package. The actual layout of everything but the antenna should be pretty easy but the soldering will be a bitch. If you design a PCB TI provides a document with specifications so you can layout a PCB antenna or select a COTS antenna. A CC430 dev board would be a good place to start, even if you just grab the documentation as a starting point in your design.

There are a few things that I consider critical designing a PCB - high power circuits (size traces appropriate so they don't explode), high speed circuits (careful routing to prevent issues with slew or noise) or RF (graphflhadsfph). Stuff like crystals are also of concern, but it's not difficult to get something that works there long as you don't get crazy with spreading out the crystal and caps from the IC.

The magic blue smoke thread in DIY has a few more people with experience on this topic as well.

EDIT:
http://www.ti.com/lit/an/swra227e/swra227e.pdf for the PCB antenna.
http://www.ti.com/lit/an/slaa462/slaa462.pdf for the balun design; I'm not really sure if the device will 'work' (even if non-ideally) without it, but if you're designing it you might as well do it right. For designing the balun I recommend following their schematic and layout perfectly. At RF frequencies, the components do not operate in the same way as they do in (relatively) low frequency situations. As soon as your wavelengths start getting smaller than the components, you need to be careful with how you do your modeling. I recommend letting the TI engineers do the hard work :toot:

Delta-Wye fucked around with this message at 20:21 on May 15, 2013

Delta-Wye
Sep 29, 2005

Otto Skorzeny posted:

Probably he means using classes as ersatz namespaces.

This seems like an unnecessary reason to use C++ over C. To be honest, I have done embedded C++ development for an 8-bit micro (for an arduino library :v:) that used inheritance and polymorphism. OOP lets you do some nice convenient stuff, but the overhead is expensive in both ROM and cycles. In theory the RAM usuage should be pretty similar except for vtables or whatever equivalent system the compiler uses.

I've also done some embedded dev on an ARM core running Linux and at 800MHz who gives a gently caress how efficient it is?

Delta-Wye
Sep 29, 2005

evensevenone posted:

Don't waste your time. An arduino/arduino clone is under $20.

They're called BASIC stamps because they literally run BASIC. I don't think there has been much improvement on them in 8-10 years, and you won't be able to find accessories or much help on them besides websites from 2005 and old entry-level books that just tell you how to blink LEDs.

BASIC is a totally suitable language for all things - ask Mug :colbert:

Please don't buy one, they were cool when I was in HS and that was a loooooong time ago. Imagine coming in here and asking about getting a pentium 2 instead of a modern processor because it's cheaper

Delta-Wye
Sep 29, 2005

Malcolm XML posted:

Ti ships them for free but it takes a while. Really nice hardware and a closer to metal feel than arduino

This is very true, and while I love the MSP430 platform, it can be a bit overwhelming for new folks. A lot of the low-power features result in complicated configuration due to the several clock domains. IMHO, anyways.

Delta-Wye
Sep 29, 2005

EpicCodeMonkey posted:

Which documentation? The most up-to-date is the one we post inside Atmel Studio, or on the "Webdoc" documentation site at http://www.atmel.no/webdoc/. The 32KB restriction was lifted long, long ago and all the new documentation should be fixed up, so if there's still some old references to the limit in the official documentation I can fix them up.

I had to reread this several times to figure out what you meant by "I'll fix the documentation". And now that I've figured it out... :patriot:

Delta-Wye
Sep 29, 2005

Martytoof posted:

e: Oh man. Apparently it's all in the datasheet as well, only for some reason Atmel decided to call it straight up TWI instead of I2C. Oh, the follies of being inexperienced :downs:

Licensing issues with Phillips :argh:

Delta-Wye
Sep 29, 2005

Victor posted:

$50 is definitely worth it... compared to real logic analyzers that's pocket change! Looking at the Bus Pirate, it seems like it might not be fast enough to debug something like a buggy I2C implementation. Wikipedia says its logic analyzer ability maxes out at 1MHz, which isn't that great if your I2C bus is running at 400kHz.

The logic analyzer on the bus pirate isn't what you would use to test i2c. It can sniff i2c directly, and I think it will dump out information about bad data. When you say buggy, do you mean bad bits in the USART or incorrect traffic?

Delta-Wye
Sep 29, 2005

Silver Alicorn posted:

If you think TI documentation is sparse you should check out ST's microcontroller docs. I had a much harder time figuring out STM32F0 versus MSP430 stuff.

Their MSP430 stuff is good, and I've found their general IC stuff is okay. Their DSP and ARM documentation is not as nice in my experience.

Delta-Wye
Sep 29, 2005

taqueso posted:

I'd like to make a composite USB device that acts as a virtual serial port and storage device. Lots of uCs will work for this, of course, but I was hoping someone here might have a recommendation for something with a good USB library or sample code. Cheapish dev tools would be cool.

If you want to go that way, the Linux usb gadget stuff in the kernel will provide that if you have a processor (arm, most likely) that will run linux.

Delta-Wye
Sep 29, 2005

hendersa posted:

If you're creating a VHDL core, then you should perform your testing of the core via VHDL simulation and verify that the core is correct prior to moving up to higher level testing at the assembly level. Basically, you'll set up a testbench that instantiates your core and then loops through a set of hardcoded asm instructions. From the core's point of view, it is fetching instructions from memory. But, the testbench doesn't really care about that, since it is simulating the memory accesses and feeding your hardcoded cases directly into the core. The testbench is a VHDL loop construct that iterates through two data structures: the data that you're pushing into the core on each cycle and the results that you expect back. Add cases in the testbench for each case for each opcode (one case that exercises the carry, overflow, etc. flags, cases for extra addressing modes, etc.).

I will be the first to admit this takes a long time to set up. But, it also serves as a regression test for future modifications. Just make your core changes and then rerun the testbench and see if you broke anything. Once you verify that the opcodes are behaving properly, THEN you can move onto building an assembler that generates correct binaries.

I like doing this, but I use systemverilog instead. gently caress doing file access in VHDL, and I haven't used a modern compiler that can't handle mixed-mode projects.

Delta-Wye
Sep 29, 2005

No Gravitas posted:

Basically, most of the thing is there. I'm about a month of concentrated effort from finishing.

And no, this isn't an old game system. It is just a workhorse MCU. You know, run a washing machine kind of device? Yeah, like that.

You're blueballing me man :( I'm hoping this is some awesome eccentric PLC controller or the like.

Delta-Wye
Sep 29, 2005

Martytoof posted:

Question: I'm kind of fuzzy on the PIC infrastructure. How much do the optimization limitations of their free compiler actually affect you guys? I am imagining scenarios where you really only start to see it if you have some crazy large firmware you've designed and for like 99% of users out there their free implementation is probably fine?

All this talk about microchip got me thinking about PICs and I think I'm going to pick up a cheap pickit 3 and just give their thing a whirl. Why not, right?

When I'm writing PIC firmware I'm usually doing something relatively simple on a larger dsPIC or similar, lots of 10-15 instruction basic blocks that usually move a piece of data and do a small amount of arithmetic. These blocks usually reside in interrupts, although sometimes I set flags/wake up in the interrupts and do data processing in a superloop.

Either way, I don't think there is a whole lot of room for optimizations and I don't think I've ever gotten close to the rom size limits on these parts. Sometimes I will write code in a very verbose way and there are probably some trivial optimizations there, but for the most part it seems okay without. I've also done timing by counting instructions (:ninja:) and I hate to think what optimizing compilers would do to that technique.

Delta-Wye
Sep 29, 2005

isr posted:

One super-loop alternative that's not an RTOS is statemachines. There's an interesting book called "Practical UML statecharts in c/c++" by Miro Samek. Most of the book's examples use his statechart software, licensed at a reasonable fee of course. All of the concepts are described and explained very well, so you could also write your own if you wanted to.

The basic idea is that of active objects. Active objects pass messages back and forth to each other, a scheduler selects which object gets to read it's messages and when. When an AO is dispatched it pop's its message from it's queue, sends messages to other objects, and runs to completion.

So if you use his framework, you get a nice UML statechart entry software interface in which you tie to your libraries, and off it goes.

I read that book recently. It's a really neat application of state machines; the hierarchical nature gives a ton of flexibility and power. It's nice not having to handle every event in every state; when unrecognized events occur, they can bubble up the hierarchy until they get handled. That said, it was used for a C++ app that ran on a relatively powerful computer (64K was not a lot) so the overhead worry was negligible.

Delta-Wye
Sep 29, 2005

PDP-1 posted:

I'd assume that the physical interface must be optoisolated, so the power supply of the laptop floating slightly relative to the dev board shouldn't be an issue, right? Maybe the laptop USB port can't supply enough power to run the programmer?

This is what I would guess. Flashing can be a bit of a current hog. I wouldn't have guessed it would have been enough to reset everything, but who knows.

So, all of this talk about superloops and RTOS's has gotten me thinking about a design pattern I used to use that always made me uneasy. When doing power sensitive applications on the MSP430 platform, making interrupts fast and efficient so the cpu can go back to sleep is important. Removing an instruction here or there can add weeks of runtime, if not months. I would usually set it up so that the processor is dormant almost all of the time waiting for an interrupt to wake it up. If the interrupt required more than a tiny bit of processing, I would often have it set a flag and the main loop would process it before going back to sleep. In rough psuedocode:

code:
int main {
  while (1) {
    if (flag & BIT0) {
      process_interrupt_1();
      flag &= ~(BIT0);
    }
    if (flag & BIT1) {
      process_interrupt_2();
      flag &= ~(BIT1);
    }
    if (flag & BIT2) {
      process_interrupt_3();
      flag &= ~(BIT2);
    }

    // if all work is done, sleep
    if (!flag)
      LOW_POWER;
  }
}

void interrupt1 {
  // called when serial data comes in
  // flag is set, processor is awake at exit
  flag |= BIT0;
}
If an interrupt fires, it will leave the processor awake. The processor re-runs the superloop reading the flags and doing the correct processing (for instance, reading a value out of the serial data_in register and storing it) before hitting the low power command again. My issue is a perceived race condition between the !flag comparison and the low power call. The main loop should keep executing until all of the flags are cleared, and then go to sleep. It is possible that an interrupt could fire there, and the processor goes to sleep without rechecking the flags, missing it until the next interrupt fires.

I never had a situation where this issue really mattered, but I feel like there is probably a better solution out there for achieving the behavior I want without this issue. I found it nice to be able to separate the processing from the interrupts. It makes interrupt priority easier, I think, and makes managing relatively long computations all interleaved by random interrupts a lot easier. Any ideas on a way of working around the race condition? I may just need to abandon this approach for things where missing an interrupt would be a problem.

Delta-Wye
Sep 29, 2005
To get easy animation, you need a method of pegging your refresh rate to walltime, and the arduino provides the milli() function for just that. You can either use the milli() value directly as your frame index, or track elapsed time.

It looks like you're leaning towards tracking elapsed time, which is pretty straight-forward. I'd do something like this:

code:
void drawframe(void) {

    static unsigned long next = 0;

    if (millis() > next) {
        // do your image generation here
        // set frame index, draw, update screen, etc
        next = millis() + 17;
    }

}
If you wanted to make it slick, you can pass in an argument that is a pointer to the light bar/framebuffer you want modified, and just call it something like:
drawType1(&left);
drawType2(&right);
etc...

What a great opportunity to use function pointers! :eng99: Your main code just calls a function pointer and doesn't have to care what the current draw function is. Say your function prototype is:
code:
void drawOp(int*);
You can create an array of function points and just store a 'currently drawing' index of all of your draw ops.
code:
void (*drawOp[3]) = {drawOp1, drawOp2, drawOp3};
int OpIdxL = 1;
int OpIdxR = 2;
drawOp[OpIdxL](&bufferL);
drawOp[OpIdxR](&bufferR);
I've done this and been pretty happy when dealing with a situation where one process (say your infinite main loop) is calling draw functions while something else is asynchronously changing the desired calls (say, in an interrupt). It does a good job of calling the new code at the first opportunity. There are other issues if you are going to use interrupts (global accessibility, volatile, etc) but that is the general gist.

Delta-Wye
Sep 29, 2005

TwystNeko posted:

Huh. That's getting a little too complex for me - I barely understand that, as pointers are kind of new to me. I think ... &var is a direct memory access of var? But int*?

I'm up for learning, of course. In the end, I just want something that works well, and lets me add new stuff. I'm all for "best practices", as less terrible code now means I can go back and look at it in 3 weeks and know what the hell I was doing. Slick is good, of course.

I'm less concerned with tracking elapsed time, to be honest - nothing I'm making is time sensitive at all, beyond making things look good.

I am noticing that I'm having to declare a whole lot more variables in the global scope. Is that something I should worry about? Or just roll with it?

Global variables are 'bad practice' that still shows up in embedded designs often. It's the simplest way to pass information around, especially if the project is naturally limited in scope so that you don't end up running into problems as the program gets larger (your project versus creating something like your web browser) and it has the added benefit of being fairly light-weight.

Ideally you'd collect the variables into objects and pass around the object or whatever but whatev.

I'm looking at your code on pastebin and there only seems to be a single LED matrix? Am I missing something?

Delta-Wye
Sep 29, 2005

I notice you're not declaring your local variables, but from that snippet they don't seem to be shared. If you are just making variables like newStack and m_X global so their values persist, look into making them local static variables.

http://en.wikipedia.org/wiki/Static_variable

EDIT: About them acting funny depending on what is enabled - do you have an easy way to determine the refresh rate? I assume your loop() function is calling these, can you print out millis() every execution, or maybe blink an LED?

The modulo solution is a bit weird, as the behavior is dependent on how often it is called. If you call the function once per millis() increment, things are perfect and it works as expected. If you call it much more often than once per millis() increment, it will not run for several increments, and then get refreshed repeatedly during that millis() value until it increments again. If you sample less, it will occasionally fail to sample on an even modulo and it will skip that refresh entirely until the next one comes along. The issue comes from the equality sign, I guess, but either way it isn't ideal. You may be running into a similar problem if you're tracking the next values in a similar fashion.

Delta-Wye fucked around with this message at 07:03 on Oct 15, 2013

Delta-Wye
Sep 29, 2005
Yeah, it looks like it is hanging up during the processing-heavy frames. My solution shows similar behavior if the refresh calculation times are high because the true refresh rate is really the wait + refresh calculation/draw time as the next value is not changed until the end of the draw function. Moving it to the front doesn't help, as you have more than one draw function running so only the first one will be correct.

A better solution is to use some sort of call back library and a hardware timer (much like the millis() function itself is doing) to set a flag and just draw a frame/clear the flag asap in the main if it's set. A library like http://playground.arduino.cc/Code/Metro with autoreset may be appropriate for this. There looks to be quite a few options for the arduino, so feel free to look around.

EDIT: The project looks cool and the code isn't bad. Don't knock yourself too hard.

Delta-Wye
Sep 29, 2005

JawnV6 posted:

The first intern prototype was derailed for a week when their cheap arduino knockoff turned out to nonfunctional. Was one of those onion peeling weeks when they finally traced it back to the cheap board not having the right parts on it. So I'm a little wary of going that route :)

I want to do a rewrite in C actually. The EE's time is more constrained than mine. I've been working in the comfort of managed languages and IDE's too long, need a return to the basics.

Any reason you couldn't just knock out an easy dev board of your own? If you're willing to program the bare processors, you don't need a whole lot of parts and then you can make the footprint whatever you want. Should be trivial to beat the $30 mark too.

Delta-Wye
Sep 29, 2005

Corla Plankun posted:

Do you all think it is possible to reprogram a microcontroller over a serial bus with one master and multiple slaves?

The application is basically an accessible master node and a bunch of physically inaccessible slave nodes. When it comes time for a firmware update, it would be awesome if I could reprogram the slave nodes from the master node's bus connection (or even just using the master node). But this is a really weird thing to do and I can't find any information about it on the internet.

In this situation, all nodes would be reprogrammed with the exact same firmware, so it would be totally okay if the reprogramming worked globally.

Is the bus one-to-all or master->single slave? Is it a popular bus like I2C or something?

Adbot
ADBOT LOVES YOU

Delta-Wye
Sep 29, 2005

Corla Plankun posted:

Do you all think it is possible to reprogram a microcontroller over a serial bus with one master and multiple slaves?

The application is basically an accessible master node and a bunch of physically inaccessible slave nodes. When it comes time for a firmware update, it would be awesome if I could reprogram the slave nodes from the master node's bus connection (or even just using the master node). But this is a really weird thing to do and I can't find any information about it on the internet.

In this situation, all nodes would be reprogrammed with the exact same firmware, so it would be totally okay if the reprogramming worked globally.

If you are able to address slaves individually, I don't see why it would be impossible but you may need to write a custom bootloader. I haven't seen anything using RS-485 specifically, at any rate. AFAIK, all you would need is a microcontroller that can reprogram it's own flash.

For the bootloader, it could be as simple as starting up, waiting a bit to see if it's supposed to be programmed, and then jumping into the system code. There are lots of examples of this part. If it's supposed to be programmed, it reads in data and replaces the current system code in flash. You may be able to crib a bootloader from an existing project like Arduino.

  • Locked thread