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.
 
  • Post
  • Reply
mod sassinator
Dec 13, 2006
I came here to Kick Ass and Chew Bubblegum,
and I'm All out of Ass
For just flashing some lights in a sequence I think delay() is fine. If you're doing something more advanced like communicating over serial, and flashing lights, etc. then it makes more sense to do things without blocking.

Adbot
ADBOT LOVES YOU

Bad Munki
Nov 4, 2008

We're all mad here.


Or to use some external light flasher like a ws2801 or something.

jovial_cynic
Aug 19, 2005

Kasan posted:

Private video is private. :smith:

I told you not to get excited about it.


Fixed.

https://www.youtube.com/watch?v=o6oFqNHbDlU

nightchild12
Jan 8, 2005
hi i'm sexy

Sagebrush posted:

I think there's also a way to fire a timer interrupt if you need microsecond-precision timing. If you're already using a method like this, ignore and carry on.

There is a way to do this, but the standard Arduino library doesn't support it. To use interrupts properly, you have to find another library or poke bits into the AVR registers directly. I prefer to access the AVR registers directly. Keep in mind, if you do stuff with interrupts (especially timer interrupts), you can easily break other Arduino-provided functions (like PWM, since it relies on timer interrupt functions to work).

Here's how you set up a timer interrupt on an ATTiny2313, taken from an LED matrix project I'm working on. A quick check of the datasheet shows that this looks like it should work with the ATMega328 as well. Example assumes 1MHz CPU frequency:

quote:

//
// necessary includes
//
#include <avr/interrupt.h>

//
// Timer0 Comparison A Interrupt Vector Interrupt Service Routine //
// runs code in the function when timer0 reaches the compA value
// then returns and runs at least one instruction from where it left
//
ISR(TIMER0_COMPA_vect)
{
// do stuff here
}

//
// Timer0 Comparison A Setup
//
// Timer0 set "Clear on Timer Compare" mode, register TCCR0A |= 0b00000010 (WGM01 = 1, WGM00 = 0)
// in CTC mode, Timer0 counts up from 0 until it hits the value of OCR0A, then sets Timer0 to 0 and fires the interrupt
TCCR0A |= (1<<WGM01);
// Timer0 output compare match A interrupt enable, register TIMSK |= 0b00000001 (OCIE0A = 1)
// enables the interrupt so the timer actually fires it off instead of just counting up to OCR0A and resetting to 0
TIMSK |= (1<<OCIE0A);
// Timer0 clock select /8 prescaler (125KHz), register TCCR0B |= 0b00000010 (CS02 = 0, CS01 = 1, CS00 = 0)
// sets the timer0 prescaler, so that timer0 only counts once every 8 clock cycles
TCCR0B |= (1<<CS01);
// Timer0 Output Compare A (3125Hz refresh), register OCR0A = 40
// value of OCR0A, since I use a 1MHz clock and set the prescaler to /8, this fires off at a 3125Hz rate (1,000,000 / 8 = 125,000 / 40 = 3,125)
OCR0A = 40;
// enable global interrupts so that interrupts can actually fire
sei(); // global interrupt enable

The above makes it so that the interrupt fires at 3125Hz and does whatever you have in the ISR. You can change the prescaler and Output Compare A values to change the rate at which the interrupt fires. I believe that the ATMega328 has 3 timers, each with a Compare A and Compare B plus overflow interrupts, which you can be clever with and stretch out to get a whole lot of different interval timer interrupts out of.

With the above, assuming a 1MHz clock, if you want a 50ms delay between interrupts firing, you'd want to set the prescaler to /256 [ TCCR0B = 0; TCCR0B |= (1<<CS02); ] and the compare value to 195 (1,000,000Hz / 256 = 3906.25 / 195 = reciprocal of 49.92ms) or 196 (1,000,000Hz / 256 = 3906.25 / 196 = reciprocal of 50.176ms). Or use Timer1 since it's 16 bit and can actually get the exact 50ms timing.

To do it with an Arduino running at 16MHz, I think you'd need to use the 16 bit Timer1, since Timer0 and Timer2 are 8 bit and can only get up to 16,000,000Hz / 1024 = 15625Hz / 255 = ~61.275Hz = ~16.32ms max delay between triggering interrupts. Assuming my math isn't off, of course.

Possible prescaler values are /1, /8, /64, /256, and /1024. Timer compare values are 8-bit for Timer0 and Timer2 and 16-bit for Timer1 (same size as the timer counters).

edit: If you do use interrupts, I believe that it's generally considered best practice to keep the ISR as short as possible so you aren't blocking in the interrupt for longer than necessary. Especially never let an ISR get big enough that another interrupt might trigger during it, unless you really really have to and account for the possibility.

nightchild12 fucked around with this message at 05:51 on Apr 5, 2014

Amberskin
Dec 22, 2013

We come in peace! Legit!

nightchild12 posted:

There is a way to do this, but the standard Arduino library doesn't support it. To use interrupts properly, you have to find another library or poke bits into the AVR registers directly. I prefer to access the AVR registers directly. Keep in mind, if you do stuff with interrupts (especially timer interrupts), you can easily break other Arduino-provided functions (like PWM, since it relies on timer interrupt functions to work).


Wasn't it posible to brick the arduino reprogramming the timer interrupts? I remember to have read something about breaking the bootloader so rendering the Arduino bricked until you can reinstall it.

I can't find it in google though, so perhaps I'm wrong.

nightchild12
Jan 8, 2005
hi i'm sexy

Amberskin posted:

Wasn't it posible to brick the arduino reprogramming the timer interrupts? I remember to have read something about breaking the bootloader so rendering the Arduino bricked until you can reinstall it.

I can't find it in google though, so perhaps I'm wrong.

All I can find is this https://forum.sparkfun.com/viewtopic.php?f=32&t=30417 and I'm not sure how that managed to brick an Arduino. Maybe it's possible for an ISR to overwrite part of the bootloader or the bootloader needs those interrupts for something? I've seen a ton of tutorials on using interrupts via an Arduino (like http://www.instructables.com/id/Arduino-Timer-Interrupts/ which looks pretty good) and never seen problems with it breaking the bootloader mentioned.

mod sassinator
Dec 13, 2006
I came here to Kick Ass and Chew Bubblegum,
and I'm All out of Ass

Amberskin posted:

Wasn't it posible to brick the arduino reprogramming the timer interrupts? I remember to have read something about breaking the bootloader so rendering the Arduino bricked until you can reinstall it.

I can't find it in google though, so perhaps I'm wrong.

Watchdog--earlier Arduinos wouldn't reset the watchdog in their bootloader, so if it was enabled they would start to boot but get stuck in a loop of the watchdog resetting them.

Amberskin
Dec 22, 2013

We come in peace! Legit!

mod sassinator posted:

Watchdog--earlier Arduinos wouldn't reset the watchdog in their bootloader, so if it was enabled they would start to boot but get stuck in a loop of the watchdog resetting them.

That is it. It was the watchdog, not the timers "per se".

Bad Munki
Nov 4, 2008

We're all mad here.


Trying to program an attiny45 from a teensy 3.0 in the arduino environment. So far, not having any luck, but this is the first time I've tried this sort of thing so hopefully it's just growing pains.

So I've got this board that's really just a glorified LED light board, not a matrix or anything, they're just all controlled by a fet via one of the tiny's pins, nothing special there. On board 5v regulator, power filtering, all that jazz. If I jump the control pins for the lights, everything lights up just great. Voltage on the tiny checks out as well. Anyhow...

I've connected the tiny to the teensy as follows:
code:
tiny     teensy
1        10 SS
5        11 MOSI
6        12 MISO
7        13 SCK
Here's the pinout for the teensy 3.0:


And because the SPI labels aren't what I expected on there, there's a table on this page which has them using the normal miso/mosi/etc names: http://www.pjrc.com/teensy/td_libs_SPI.html which I've put in my connection table up above. They happen to match the standard arduino SPI pin numbers.

So I compiled and uploaded the ArduinoISP sketch to the teensy, that went without issue. I then attempted to burn the boot loader onto the tiny (it's fresh from the factory) using the 1mhz internal clock option and I keep getting the following output:
code:
avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.
So of course I checked the connections. Checking from the top side of the teensy to the actual pin on the tiny, I get less than 10Ω across all the pins in question. Unless I have my pins crossed (I don't according to the above connection table, but is my table wrong?) I can't figure out what's going on here. The wires are all good, the breadboard is good, the connections are physically good.

There are a couple differences with this system from the examples, of course:
1) The attiny45 in question is in its destination circuit, but I've disconnected anything from all the pins (except power/ground). I need it to be in its circuit because it's an SMD component with a pretty small pitch. I broke the pins out to some larger pads that I've temporarily soldered my jumper wires to.
2) The tiny is using the power supply that is on-board this device, rather than using the +5v/gnd from the programmer arduino like other setups describe. I feel like that shouldn't be a problem, though. The power supply checks out.
3) I'm programming with a teensy, instead of a vanilla arduino. The sketch compiled fine, though, and I'm pretty sure I've got all the pins right.

I've been googling around on this and I'm not coming up with anything. Any ideas? Here's a picture of the actual setup, I tried to arrange the wires so it's possible to visually follow them. My apologies for only using two colors, it's what was within reach when I started this:

(Don't mind the second teensy, that's not being used here, it's just hanging out.)


And here I traced the wires in different colors to make it easier to follow them, as well as drew the traces to the tiny in the same colors, and marked pin 1 with a white dot:



I know there are a couple other components visible on the board, but I've strategically removed resistors and caps such that they aren't actually connected to the tiny at all. The one exception being that trimpot just north of the tiny, but in that case it's only connected to anything on the sweeper pin, as r11 and r12 are not currently present, so it's just dangling.

That turned in to a lot of info, but I wanted to be thorough. If anyone has any ideas, I'm all ears.

Bad Munki fucked around with this message at 04:57 on Apr 6, 2014

Sagebrush
Feb 26, 2012

Try using the 8mhz internal pscillator fuse settings first. I've had some problems with the other clock rates in the past.

Next, are you sure that you installed the cores properly? That also can be a mess sometimes.

Using a teensy 3.0 worries me, though. It's not got an AVR core, and it's quite possible that the ArduinoISP sketch doesn't work properly with the Teensy 3 at all. The 2.0 and the 2.0++ are the ones that are closest to a real arduino.

Aurium
Oct 10, 2010

Bad Munki posted:

Trying to program an attiny45 from a teensy 3.0 in the arduino environment. So far, not having any luck, but this is the first time I've tried this sort of thing so hopefully it's just growing pains.

Here's someone else trying to use arduinoISP with a teensy 3.0. Some initialization code seems to be in the wrong place. After they moved it, it worked.

Bad Munki
Nov 4, 2008

We're all mad here.


Aurium posted:

Here's someone else trying to use arduinoISP with a teensy 3.0. Some initialization code seems to be in the wrong place. After they moved it, it worked.

Huh. I tried that, but it didn't seem to help. The search continues. :/


Sagebrush posted:

Try using the 8mhz internal pscillator fuse settings first. I've had some problems with the other clock rates in the past.

Next, are you sure that you installed the cores properly? That also can be a mess sometimes.

Using a teensy 3.0 worries me, though. It's not got an AVR core, and it's quite possible that the ArduinoISP sketch doesn't work properly with the Teensy 3 at all. The 2.0 and the 2.0++ are the ones that are closest to a real arduino.

Well, I do happen to have a teensy 2.0++, I'll give that a shot. I also have a regular arduino uno, but it's currently in the ceiling at the makerspace controlling the front door. Gonna replace it with one of the teensy boards that pjrc donated, I guess this is motivation to get that done. :downs:

SomethingLiz
Jan 23, 2009
Raspberry Pi is kind of like Arduino, right? I thought this belonged here better than the regular projects thread. I made an internet powered gumball machine! The gumball machine is powered by a Raspberry Pi running Node.js. A button on an Android app triggers the Pi to start turning a stepper motor, which causes the gumball machine to dispense a prize.

Video and image here: http://rettgergalactic.com/blog/2014/04/a-raspberry-pi-powered-gumball-machine/

CygnusTM
Oct 11, 2002

SomethingLiz posted:

Raspberry Pi is kind of like Arduino, right? I thought this belonged here better than the regular projects thread. I made an internet powered gumball machine! The gumball machine is powered by a Raspberry Pi running Node.js. A button on an Android app triggers the Pi to start turning a stepper motor, which causes the gumball machine to dispense a prize.

Video and image here: http://rettgergalactic.com/blog/2014/04/a-raspberry-pi-powered-gumball-machine/

There is a Raspberry Pi thread.

SomethingLiz
Jan 23, 2009
Oh neat, I never venture into the Hardware/Software area. Thanks for pointing that out.

Bad Munki
Nov 4, 2008

We're all mad here.


So a funny quirk I ran across: if you're using the Keypad library, you need to include it FIRST if you're targeting the teensy platform. It's due to some mutual inclusion of Arduino.h that isn't handled properly, it's totally fixable, but I like my code to work on a vanilla installation without local changes to the default libraries. Helpfully, the errors that come back have nothing to do with that and are simply complaining about syntax errors and expected classnames. :downs:

Bad Munki
Nov 4, 2008

We're all mad here.


What the everliving hell. I am absolutely stumped by this.

Here's the setup:

Arduino uno, pins 2, 3, 4, 5, 6, 7, 8 are connected to the columns and rows of a numeric keypad. Pins 11 and 13 are connected to the data/clock pins of a ws2801 led strip. Pin 9 is connected to an optocoupler.

The arduino watches the keypad for input, builds up an input sequence, and when the user enters # or *, it authorizes the entered code and possibly unlocks a door via the optocoupler. It uses the led strip as decoration around the keypad and feedback (i.e. breathing blue for idle, rainbow for reading input, red for access denied, green for access granted.)

For the last six months, it's been running on an arduino uno without issue. It was one of my personal arduinos, though, and we had some teensy 3.0s donated to the space, so I was swapping it out for a teensy because I needed it back for other stuff.

Here's the thing: I'm getting some incredibly weird behavior, and I've narrowed the apparent cause down to a single line of code. The thing is, that line of code is simply taking a String and appending the most recent keypad char entered onto the end of it via the += operator. The bizarre behavior is that when you press one of the numbers on the keypad, it reads it perfectly well, and then some sort of input loops kicks in, generating random input digits every quarter second or so, until you terminate the sequence by entering # or *.

I'm confident it's not a hardware issue with the keypad or the wiring thereof: at one point, I changed the keymap in the arduino code to treat all the buttons except one as if they were # symbols. Pressing any of them terminated the sequence as expected, and the one I left a normal digit induced the loop.

If I comment out the one line, the loop does not happen. Pressing a key garners the correct response, and it can be dumped to the Serial monitor, and no repeat happens. If I leave the line in, the key is read correctly and then the input loop starts generating its random key press a few times a second until I hit #.

The line in question is the one marked in the code below, towards the end of loop(). I've tried appending and concatenating in various ways, to no avail. I've tried manually setting the value of key to NO_KEY after it's appended to the code, just in case something was carrying over, but no luck. I tried all sorts of random poo poo for four hours, standing in front of the door with my laptop on a ladder and a usb cable up into the ceiling, and I am flat out of ideas.

At this point, I'm getting suspicious of the teensy libraries. There was the problem noted in the header section with the ordering of the keypad includes, and I'm wondering if there's more there that's still causing problems. Like I said, this all works fine on an uno, the only change was swapping the uno for a teensy 3.

It's a hard system to test away from the actual installation, unless you happen to have a keypad and led strip, although the led stuff can be stripped out and the bug remains. I left it in here because there has to be some weird interaction SOMEWHERE, and I don't want to hide it by removing something *I* think is innocuous but really isn't.

Here's the code, in its entirety, raw and uncut:

code:
#include <Keypad.h> // This MUST be first when building for teensy due to some header issues
#include <FastLED.h>
#include <math.h>

#define DOOR_PIN 9

#define NUM_LEDS 12

struct CRGB leds[NUM_LEDS];

const byte rows = 4; //four rows
const byte cols = 3; //three columns
char keys[rows][cols] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[rows] = {2, 3, 4, 5}; //brown, purple, red, white
byte colPins[cols] = {6, 7, 8}; //black, blue, orange
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );

String code = "";
unsigned long codestart = 0;
unsigned long animation_offset = 0;

void setup() {
  digitalWrite(DOOR_PIN, LOW);
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect
  }
  
  pinMode(DOOR_PIN, OUTPUT);
  LEDS.addLeds<WS2801, 11, 13, BGR, DATA_RATE_MHZ(1)>(leds, NUM_LEDS); //green, yellow
  LEDS.showColor(CRGB(255, 100, 0));
  
  delay(1000);
  animation_offset = 0;
}

void loop() {
  digitalWrite(DOOR_PIN, LOW); // just keep doing this forever for safety's sake
  if(animation_offset > millis()) { // need to account for millis() rolling over around 50 days. Might glitch animation for a frame
    animation_offset = 0;
  }
  if(code.length() > 0 && (millis() - codestart) > 5000) { //5-second timeout on entry
    code = "";
  }
  if(code.length() <= 0) {
    status_idling();
  } else {
    status_reading();
  }
  char key = keypad.getKey();
  if(key != NO_KEY) {
    codestart = millis(); //reset the timeout
    if(key == '#' || key == '*') { //submit for authorization on these two keys
      if(code.length() <= 3) { //codes have to be at least four digits
        alert_deny();
        code = "";
      } else {
        if(authorize(code)) { //authorize the code via serial
          digitalWrite(DOOR_PIN, HIGH);
          alert_allow();
          digitalWrite(DOOR_PIN, LOW);
          code = "";
        } else {
          alert_deny();
          code = "";
        }
      }
    } else { //for all non # or * keys, just append it to the currently-entered code
//=================================
//THIS LINE RIGHT loving HERE WHAT THE gently caress
      code += key;
//=================================
      Serial.println(key);
      Serial.println(code);
    }
  }
}

boolean authorize(String code) { //given a PIN, check authorization via serial
  //Serial.println(code);
  // temporary hard-coded code
  if(code.equals("1593570")) {
    return(true);
  } else {
    return(false);
  }
  /*
  status_thinking();
  Serial.println("Code: " + code);
  while(!Serial.available()) {
    status_thinking();
  }
  char r = Serial.read();
  if(r == 'y') {
    return(true);
  }
  return(false);
  */
}

void status_idling() { //slowly "breathe" blue, single frame per call
  if((millis() - animation_offset) % 10 == 0) {
    LEDS.showColor(CRGB(0, 0, floor((sin(float(millis() - animation_offset) / 1000.0) * 0.5 + 0.5) * 255)));
  }
}

void status_reading() { //spin a rainbow, single frame per call
  if((millis() - animation_offset) % 10 == 0) {
    fill_rainbow(leds, NUM_LEDS, float(millis() - animation_offset) / 4.0, 20.0);
    LEDS.show();
  }
}

void status_thinking() { //quickly "breathe" yellow, single frame per call
  if((millis() - animation_offset) % 10 == 0) {
    int v = floor((sin(float(millis() - animation_offset) / 100.0) * 0.5 + 0.5) * 255);
    LEDS.showColor(CRGB(v, v, 0));
  }
}

void alert_deny() { //flash red three times and fade out after the third, blocking during animation, takes roughly 1
  LEDS.showColor(CRGB(255, 0, 0));
  delay(100);
  LEDS.showColor(CRGB(0, 0, 0));
  delay(50);
  LEDS.showColor(CRGB(255, 0, 0));
  delay(100);
  LEDS.showColor(CRGB(0, 0, 0));
  delay(50);
  LEDS.showColor(CRGB(255, 0, 0));
  delay(100);
  LEDS.showColor(CRGB(0, 0, 0));
  delay(50);
  LEDS.showColor(CRGB(255, 0, 0));
  delay(100);
  LEDS.showColor(CRGB(0, 0, 0));
  delay(50);
  LEDS.showColor(CRGB(255, 0, 0));
  delay(100);
  for(int ii = 255; ii >= 0; ii-=4) {
    LEDS.showColor(CRGB(ii, 0, 0));
    delay(10);
  }
  animation_offset = millis();
}

void alert_allow() { //illuminate green and fade out after a bit, blocking during animation, takes roughly 5
  LEDS.showColor(CRGB(0, 255, 0));
  delay(2500);
  for(int ii = 255; ii >= 0; --ii) {
    LEDS.showColor(CRGB(0, ii, 0));
    delay(10);
  }
  animation_offset = millis();
}
If I'm not describing the symptoms well, I can get a video of the keypad next to the serial monitor to make it more obvious what I'm talking about, but that'll have to be tomorrow night when I'm back down there. I was hoping to FIX this when I'm down there tomorrow night, though, so if anyone has any ideas in the mean time, I'm all ears. Thanks in advance. :)

Bad Munki fucked around with this message at 04:13 on Apr 9, 2014

Sagebrush
Feb 26, 2012

Sorry, no solution to your problem, but rather an unrelated question.

Hypothetically, if you had a 12 volt line and you just wanted to figure out if it was energized or not, could you put it directly into an Arduino digital pin as long as you used a proper (1000+ ohm) resistor? Would external current control be enough to prevent the chip from burning up, or would having the higher voltage going in just totally screw with the logic?

mod sassinator
Dec 13, 2006
I came here to Kick Ass and Chew Bubblegum,
and I'm All out of Ass
I would pull out the usage of the String class and switch to using char[] buffers with standard c string manipulation functions (from string.h or cstring). The unfortunate thing with Arduino's String class is that is uses dynamic memory, which can lead to subtle heap fragmentation issues or worse. When there's only a few kilobytes of memory, allocating and deallocating memory a lot can lead to fragmentation very quickly. Each time you append or assign to the string it might need to do allocation/deallocation.

One thing to try before ripping out the String code though is allocating a chunk of space for the String up front in the sketch's setup. This will hopefully reduce the need to allocate more space later. For example to preallocate 10 characters, in the setup try adding:

code.reserve(10);

If you think the string might grow longer than 10, bump the size of memory allocated up. This won't change the length of the string (it's still assigned an empty string value from the start), it only increases the space available to store data.

Ultimately I would try to look at switching to c strings that are allocated on the stack (i.e. size is known at compile time). It's a little more annoying but will remove the headache of heap fragmentation and corruption issues.

mod sassinator
Dec 13, 2006
I came here to Kick Ass and Chew Bubblegum,
and I'm All out of Ass

Sagebrush posted:

Sorry, no solution to your problem, but rather an unrelated question.

Hypothetically, if you had a 12 volt line and you just wanted to figure out if it was energized or not, could you put it directly into an Arduino digital pin as long as you used a proper (1000+ ohm) resistor? Would external current control be enough to prevent the chip from burning up, or would having the higher voltage going in just totally screw with the logic?

I would be careful, from the ATmega328p datasheet the maximum voltage on any pin is Vcc+0.5V (where Vcc is 5 volts on almost all Arduinos): http://www.atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet.pdf

You could probably make a voltage divider with two resistors to cut the 12V into about 5V though. For example go from 12 volt line though a ~20k resistor and then a ~10k resistor to ground. At the junction of the 20k and 10k resistor it should be 1/3 of 12V, or 4V, which is enough to register as a high signal.

Sagebrush
Feb 26, 2012

That's what I had planned to do, but I wondered if there was any technical reason you couldn't use a higher voltage provided you locked the current down. I could easily see some kind of charge leakage or something being a problem.

Kasan
Dec 24, 2006

Sagebrush posted:

That's what I had planned to do, but I wondered if there was any technical reason you couldn't use a higher voltage provided you locked the current down. I could easily see some kind of charge leakage or something being a problem.

In your case you could remove the Arduino completely and just use a current limiting resistor and an LED.

Sagebrush
Feb 26, 2012

Well, no, my application is more complicated than that. Was just wondering if I could save myself some time splicing into the line (the brake, taillight and turn signal lamps on a motorcycle)

Aurium
Oct 10, 2010

Sagebrush posted:

Sorry, no solution to your problem, but rather an unrelated question.

Hypothetically, if you had a 12 volt line and you just wanted to figure out if it was energized or not, could you put it directly into an Arduino digital pin as long as you used a proper (1000+ ohm) resistor? Would external current control be enough to prevent the chip from burning up, or would having the higher voltage going in just totally screw with the logic?

An external resistor isn't enough. It's not only a power dissipated thing.

There's a few possibilities. That 12 v could hit a gate of an internal mosfet and blow it, even at very low currents. The insulating layer of a mosfet is just thick enough for the expected voltage, any thicker makes it work worse. This is similar (identical in fact) to what would happen if you overvoltaged any capacitor, even at very low currents. Similar how ESD kills things with almost no current.

Another thing that happens is latchup. You probably know about the parasitic (body) diode on a mosfet. What you may not know about is that in CMOS devices there's a parasitic SCR between transistor pairs. This SCR serves no purpose in the chip, it's just an artifact of how silicon has to be layered down. When a SCR turns on, it does not turn off until power is removed. They can be self reinforcing, once it's turn on, it turns itself the rest of the way on. The way they're managed (ie never turned on) in actual chips is by keeping them reversed biased. Of course, if you put higher voltages than expected, you could easily bring the parasitic gate high enough to turn it on.

Another thing is imagine the smallest lowest current signal diode you've ever seen. Chips are full ones thousands of times smaller these things across every pin to power and ground. If you raise a pin sufficiently above vcc, you'll turn one of these on and blow it. If it blows open, it just won't protect anymore, but if it blows closed, you'll end up with a pin that's stuck on.

jovial_cynic
Aug 19, 2005

Between VGA output, component video output, oLEDs, and other custom displays, is there any feedback here on the results of each, limitations experienced, etc.?

mod sassinator
Dec 13, 2006
I came here to Kick Ass and Chew Bubblegum,
and I'm All out of Ass
What's the platform that will be driving the display? If it's Arduino you'll have a hard time driving a VGA/component/TV display directly from the chip. The timing for generating those signals is really fast, and they generally need a framebuffer which will take way more than the 2k of memory on the chip. I've seen some Arduinos drive black and white TV (s-video) displays, but it's kind of like programming an Atari 2600 in that you need to do everything without a framebuffer.

For a little OLED or LCD display Arduinos are great though. Just be mindful that displays with a parallel interface can take a lot of pins, like 14+ pins in some cases. There are usually SPI and I2C adapters or native displays that will just a take a few pins though. Adafruit has some nice looking tiny OLED displays that I've been meaning to check out: http://www.adafruit.com/search?q=OLED There's also the classic Nokia 5100/3100 display which I've used before and had great results: http://www.adafruit.com/products/338 Again the big issue with graphic displays is usually holding the framebuffer in memory. You won't see too many displays bigger than a few hundred pixels because of the memory required to store all the pixel data.

If you're looking at a Linux-based platform like the Beaglebone Black or Raspberry Pi then the sky is really the limit as far as displays go. The Pi has a TV out built in which is nice for some simple stuff. The BBB can do LVDS to talk to some displays I believe. Both the Pi and BBB have HDMI and it's the preferred form of output. The Pi has a slightly better GPU and can do 1920x1080p whereas the BBB can only do 1280x720p I believe.

Amberskin
Dec 22, 2013

We come in peace! Legit!

jovial_cynic posted:

Between VGA output, component video output, oLEDs, and other custom displays, is there any feedback here on the results of each, limitations experienced, etc.?

I have been playing a little bit with this thing:

http://www.banggood.com/2_4-Inch-TFT-LCD-Display-Module-Touch-Panel-240-X-320-With-PCB-Adapter-p-913116.html

It is ILI9325 based, and runs relatively well using the UTFT library. There are some caveats. As mod sassinator wrote, you need a lot of pins just to drive the display (it is wired to use a 8-bit parallel interface). If you want to drive the touchpad and the SD card slot I'm afraid an arduino UNO will come out of pins. On the other hand, the UTFT library is quite big and it barely fits in a Leonardo (whose bootloader is bigger than the UNO one), and in any case you will be left with a very small flash memory free to do useful things.

Of course, If you don't want to go to the Raspberry/Beaglebone route you can always get an Arduino Mega, with more pins that you need and with plenty of flash memory space to play with.

Captain Cool
Oct 23, 2004

This is a song about messin' with people who've been messin' with you

Bad Munki posted:

1) The attiny45 in question is in its destination circuit, but I've disconnected anything from all the pins (except power/ground). I need it to be in its circuit because it's an SMD component with a pretty small pitch. I broke the pins out to some larger pads that I've temporarily soldered my jumper wires to.
2) The tiny is using the power supply that is on-board this device, rather than using the +5v/gnd from the programmer arduino like other setups describe. I feel like that shouldn't be a problem, though. The power supply checks out.
Are you powering these two devices with two separate DC power supplies? There might be a difference in the ground level. Can you try powering the teensy off of the tiny's board's supply, or powering one of the chips with a battery supply?

Bad Munki posted:

Here's the thing: I'm getting some incredibly weird behavior, and I've narrowed the apparent cause down to a single line of code. The thing is, that line of code is simply taking a String and appending the most recent keypad char entered onto the end of it via the += operator. The bizarre behavior is that when you press one of the numbers on the keypad, it reads it perfectly well, and then some sort of input loops kicks in, generating random input digits every quarter second or so, until you terminate the sequence by entering # or *.

At this point, I'm getting suspicious of the teensy libraries.
I'm not familiar with Arduino libraries yet, but I've done a fair amount of C programming. C doesn't let you overload operators -- is there a dash of C++ in the environment to do that? If so, the "+=" operator is not a basic operator for appending strings, so it's gotta be defined in a library somewhere. If not, then this code was doing something wacky before.

Sagebrush posted:

Hypothetically, if you had a 12 volt line and you just wanted to figure out if it was energized or not, could you put it directly into an Arduino digital pin as long as you used a proper (1000+ ohm) resistor? Would external current control be enough to prevent the chip from burning up, or would having the higher voltage going in just totally screw with the logic?
Use two resistors to create a voltage divider down to the voltage range of your chip. Pick high values (20k+) to minimize the current drain.

Bad Munki
Nov 4, 2008

We're all mad here.


Captain Cool posted:

Are you powering these two devices with two separate DC power supplies? There might be a difference in the ground level. Can you try powering the teensy off of the tiny's board's supply, or powering one of the chips with a battery supply?
I was using two different power supples: the teensy was being powered via usb, while the attiny was being powered by the supply on the board it's installed on. I'll try powering it from the same supply as the programmer. In any case, it SHOULDN'T be a problem anymore because I got my uno back.

quote:

I'm not familiar with Arduino libraries yet, but I've done a fair amount of C programming. C doesn't let you overload operators -- is there a dash of C++ in the environment to do that? If so, the "+=" operator is not a basic operator for appending strings, so it's gotta be defined in a library somewhere. If not, then this code was doing something wacky before.
Yeah, String objects are part of the core and that's straight out of the reference docs: http://arduino.cc/en/Tutorial/StringAppendOperator

Captain Cool
Oct 23, 2004

This is a song about messin' with people who've been messin' with you

Bad Munki posted:

I was using two different power supples: the teensy was being powered via usb, while the attiny was being powered by the supply on the board it's installed on. I'll try powering it from the same supply as the programmer. In any case, it SHOULDN'T be a problem anymore because I got my uno back.

Yeah, String objects are part of the core and that's straight out of the reference docs: http://arduino.cc/en/Tutorial/StringAppendOperator
Alright, simple enough.

My only other guess would be a difference in pullups/pulldowns between the two chips. If the input was left floating, it could pick up some random values between whatever you're doing to start and stop the input sequence. But if that's the case, as far as I can tell from your code, it should be picking up inputs all the time.

If you comment out the serial prints after the += line, does it work differently?

Bad Munki
Nov 4, 2008

We're all mad here.


Nope, it was still freaking out. I could tell because inputting a valid code and then spitting it out to serial at the very end of the input when # was pressed would show me all the random input it had caught in the interim. Removing the serial output entirely made it a little harder to check, except that I could try a valid code and it never worked, so I have to assume it was still getting the spurious input, as this code worked on the uno.

Really, just adding or removing that += was the only thing that had an effect, it's really bizarre. I've written a version that just uses a fixed-length character array, we'll see if that fixes it. Haven't had a chance to go back to the installation and try the new code with the teensy yet, though.

Also, I considered the pull-up/pull-down possibility, but pretty much ruled that out when I just changed the keycap to be all # symbols except one number key, and pressing any of the #-mapped keys would halt the random input, and as you said, I should be seeing it all the time anyhow.

Bad Munki fucked around with this message at 04:18 on Apr 15, 2014

jovial_cynic
Aug 19, 2005

Is there something I should know about being near an arduino that causes an input pin to read high?

I wired in an LED w/ resistor (just like the blink diagram), but I also wired in a switch between the 5v and pin 7 so I can test some if/then statements... but just waving my hand over the arduino board causes pin 7 to read high.

Maybe I am magical and cause electromagnetic fields to go wonky around me, but that is unlikely. But what is causing this?

Bad Munki
Nov 4, 2008

We're all mad here.


Your body and some of the hardware are probably acting as a capacitor, and the arduino is sensing it. See http://playground.arduino.cc/Code/CapacitiveSensor

jovial_cynic
Aug 19, 2005

Bad Munki posted:

Your body and some of the hardware are probably acting as a capacitor, and the arduino is sensing it. See http://playground.arduino.cc/Code/CapacitiveSensor

That link appears to involve touching the pin. I'm causing this by just hovering my hand over it. Is this a feature? It seems like it could cause significant problems if I'm trying to program the arduino to behave a certain way when a button is pressed, but the "feature" causes the input to think I'm pressing the button before I actually am.

How do I turn this off?

TheLastManStanding
Jan 14, 2008
Mash Buttons!
You turn it off by properly grounding the pin (with a high value resistor). An input that isn't connected to anything is going to float, which lets it be influenced by any stray capacitance, such as a nearby person or even the pins next to it.

Captain Cool
Oct 23, 2004

This is a song about messin' with people who've been messin' with you

jovial_cynic posted:

How do I turn this off?
You have a floating input pin. It's not really high or low by default, so you need to force a default state. You can connect a resistor from ground to the pin. Use 1kohm or more; higher values will reduce current draw while the button is pressed. The resistor will weakly pull the pin low, and then your button will strongly pull the pin high.

If the chip has an internal pull-up/pull-down on that pin, you can use that instead.

mod sassinator
Dec 13, 2006
I came here to Kick Ass and Chew Bubblegum,
and I'm All out of Ass
Yep exactly, when pin 7 isn't connected to power through the switch then it's 'floating' and the voltage is in a somewhat indeterminate state. It might go down near ground, but also might go higher if there's stray capacitance like your body moving near it. Put a large (10k-ish) resistor from 7 down to ground and it should stop the floating. If you don't put in the resistor be careful because you'll short power to ground when the switch is closed and maybe hurt your power supply or blow a fuse.

Amberskin
Dec 22, 2013

We come in peace! Legit!

jovial_cynic posted:

That link appears to involve touching the pin. I'm causing this by just hovering my hand over it. Is this a feature? It seems like it could cause significant problems if I'm trying to program the arduino to behave a certain way when a button is pressed, but the "feature" causes the input to think I'm pressing the button before I actually am.

How do I turn this off?

As the other replies told you, you can use a resistor to "pull down" the pin to ground.

You could do it the other way though. That is, connect the pin to GROUND through the switch, and activate the internal "pullup" resistor provided by the AVR MCU. You pin will read as zero when you close the switch, and as one otherwise. This thread discusses how to do it:

http://forum.arduino.cc/index.php/topic,5313.0.html

Bad Munki
Nov 4, 2008

We're all mad here.


jovial_cynic posted:

That link appears to involve touching the pin. I'm causing this by just hovering my hand over it.

A minor difference. Here's another example that doesn't involve direct contact: http://playground.arduino.cc/Main/CapacitiveSensor?from=Main.CapSense

Adbot
ADBOT LOVES YOU

jovial_cynic
Aug 19, 2005

Thanks, folks.

Next question. I've seen images where a sensor is powered and grounded at the Arduino, with the sensor wire going into one of the analog inputs. With a three-wire system like that, is it necessary that the power and ground be at the Arduino, or can the sensor be powered elsewhere?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply