- Aurium
- Oct 10, 2010
-
|
Ok, so I found an Instructables thing on how to get analog feedback output from my servos. How do I integrate that into my code in any meaningful way?
First off you'd need to figure out how the output of the analog feedback relates to the position.
Lets assume that your 0-720 degree range maps to 152-872 coming off the adc (it won't). This range is (1024-720)/2 (analog read max-the number of degrees you have / 2 to give it equal buffer size)
I also assume you've found the right math to feed servo.write the range of 0-720. this should be a simple map function of from something like 0-720 to 45-135 ( or whatever your subset of the 0-180 range of the servo ends up being) I'm calling this corrected_servo(degrees) and will just feed it a value of 0-720.
Really rough code :
so it'd go
code:void corrected_servo(degrees)
{
//45 and 135 are experimentally derived to your hardware
servo.write(map(degrees, 0, 720, 45, 135))
}
//give it a 0-720 and have it move fast
void fast_servo_move(int degrees)
{
//get current position
int current_position = analogread(feedback_pin)
mapped_degrees = map(degrees, 0, 720, 152, 872 )
//this is affected by the 152-872 range
if(mapped_degrees > current position)
{
//move to full positive if requested position is greater than current position
//note that it may be faster still if you used servo.write(180)
//written like this it would still be slow if you're close to the end.
//where as you'd never actually be at the actual extremes of the servo
//which would always give you best speed.
//if you understand why this is, I'd use servo.write(180) here.
corrected_servo(720);
}
else
{
//full negative if requested position is less than current position
//note that it may be faster still if you used servo.write(0)
corrected_servo(0);
}
//wait to get within 15 degrees
while( abs(mapped_degrees - current_position) > 15)
{
delay(10)
current_position = analogread(feedback_pin)
}
//it's close, so set the servo to the desired value
corrected_servo(degrees)
}
Once you get the appropriate ranges, I encourage you can ask for help again. Note that if you're supplying your servo with 6v the voltage of your analog feedback pot may fall outside the safe voltage range of your arduino. If you're powering it with 5v you won't have a problem. (unless you're using a 3.3v arduino)
|
#
?
Oct 5, 2015 04:08
|
|
- Adbot
-
ADBOT LOVES YOU
|
|
#
?
May 31, 2024 22:16
|
|
- PDP-1
- Oct 12, 2004
-
It's a beautiful day in the neighborhood.
|
I've never actually tried doing this, but it seems like it'd be possible to 'overdrive' the servo a bit during long moves by adding your own proportional control in code. Something like this:
code:int SV; // our setpoint variable, aka where we want to go
int PV; // our process variable, aka where the servo actually is
int SV2; // our 'overdrive' setpoint variable
int upperBound, lowerBound; // the upper and lower bounds of the range we want the servo to move through
float P; // a proportional control term that we'll have to experiment to find the right value for
while(1)
{
PV = readActualServoPositionHere();
SV2 = SV + (int)(P * (SV - PV));
if(SV2>upperBound){ SV = upperbound; }
if(SV2<lowerBound){ SV = lowerBound; }
writeNewServoDriveValueHere(SV2);
}
Just to game out how that would work, suppose our proportional constant P is 1.0f, we are starting at 0% rotation and want to go to 50% rotation. On the first iteration of the loop the overdriven setpoint is SV2 = 50% + 1.0f * (50% - 0%) or SV2=100%. This means that we're telling the servo that it's way off the mark and it should move really fast.
Now suppose the servo has turned for a bit and is at 45% rotation. The new overdriven setpoint is SV2 = 50% + 1.0f * (50% - 45%) or SV2 = 55%. In other words, as the servo approaches its final position the overdrive variable starts to slack off a bit. It's easy to see that when SV=PV, aka we're exactly where we want to be, SV2=SV so the overdrive isn't doing anything anymore.
Basically we're adding our own proportional control loop term to the servo's internal control loop to speed it up when it's far from the desired position. To find the appropriate value for P run the servo under normal load conditions and gradually increase P until the servo starts to oscillate around the setpoint position. Throttle P back to about 70% of the minimum P value that causes oscillations.
|
#
?
Oct 5, 2015 14:53
|
|
- mobby_6kl
- Aug 9, 2009
-
by Fluffdaddy
|
Just ordered an ATMEGA328-based Arduino-complatible mystery board off banggood for exactly 3 bucks with shipping. Supposedly they work fine so I'm curious if it'll do what little I expect from it.
|
#
?
Oct 5, 2015 16:03
|
|
- rawrr
- Jul 28, 2007
-
|
I bought like 3 of the Arduino Nano clones (I like that you can just plug them directly onto the breadboard, and the smaller size is also easier to integrate into projects), and they've all worked fine. I recently picked up like 6 more for $12 shipped just to have some extras.
There are also smaller Digispark/Adafruit Trinket clones based on the ATTINY, but they're only like 50 cents cheaper.
With these sort of suspiciously cheap things I tend to prefer to use aliexpress or dhgate, because they allow users to leave listing specific reviews and sort by review ratings or items sold, making it less of a crapshoot, though I haven't had problems with ones I ordered on eBay.
|
#
?
Oct 5, 2015 19:38
|
|
- TVarmy
- Sep 11, 2011
-
like food and water, my posting has no intrinsic value
|
I've had good luck with insanely cheap ebay electronic components. I imagine there's probably knockoffs, counterfeits, and bad labeling, but for hobbyist purposes they're a great deal.
If you look up prices for AVR chips, they're insanely cheap in bulk, and Arduino designs are fairly simple and open source, so cheap clones make sense. The biggest problem is probably just bad build quality. But if you're getting a board for sub-$5 when you'd normally pay $20 for an official board with the same design, it's hard to complain.
But I learned the hard way that you shouldn't buy the cheapest Taiwanese breadboard. The stiff springs are a major pain and ruin components and jumper wires that don't have a thin pin at the end.
|
#
?
Oct 5, 2015 19:54
|
|
- dirtycajun
- Aug 27, 2004
-
SUCKING DICKS AND SQUEEZING TITTIES
|
Okay, working on the project again tonight, curious if this is something that will work (besides the part where I need help fixing error "'leds_value' was not declared in this scope
'leds_value' was not declared in this scope")
code://Libraries
#include "FastLED.h"
//Setting up the MSGEQ7 processor
int analogPin = 0; // MSGEQ7 OUT
int strobePin = 2; // MSGEQ7 STROBE
int resetPin = 4; // MSGEQ7 RESET
int spectrumValue[7];
int filterValue = 80;
//# of LEDs in Strip
#define NUM_LEDS 392
//Data Pin Output
#define DATA_PIN 6
// This is an array of leds. One item for each led in your strip.
CRGB leds[NUM_LEDS];
// This function sets up the LEDs and tells the controller about them as well as setting up the processor
void setup() {
Serial.begin(9600);
pinMode(analogPin, INPUT);
pinMode(strobePin, OUTPUT);
pinMode(resetPin, OUTPUT);
analogReference(DEFAULT);
digitalWrite(resetPin, LOW);
digitalWrite(strobePin, HIGH);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}
void loop()
{
// Set reset pin low to enable strobe
digitalWrite(resetPin, HIGH);
digitalWrite(resetPin, LOW);
// Get all 7 spectrum values from the MSGEQ7
for (int i = 0; i < 7; i++)
{
digitalWrite(strobePin, LOW);
delayMicroseconds(30); // Allow output to settle
spectrumValue[i] = analogRead(analogPin);
// Constrain any value above 1023 or below filterValue
spectrumValue[i] = constrain(spectrumValue[i], filterValue, 1023);
// Remap the value to a number between 0 and 255
spectrumValue[i] = map(spectrumValue[i], filterValue, 1023, 0, 255);
Serial.print(spectrumValue[i]);
Serial.print(" ");
digitalWrite(strobePin, HIGH);
}
Serial.println();
// The actual displaying of the LEDs
for (int i = 0; i < NUM_LEDS / 2 - 1 < 154; i++) {
//this line is to get rid of background noise, change it higher if there is more noise
if (spectrumValue[i % 7] > 50) {
//and this is the line that controls LED colors as well as determining how bright
leds_value = CHSV((i / 11) * 32, 255, spectrumValue[i / 11]);
leds[i] = leds_value;
leds[NUM_LEDS - i] = leds_value;
}
for (int i = 154; i < NUM_LEDS / 2 - 1 < 238; i++) {
//this line is to get rid of background noise, change it higher if there is more noise
if (spectrumValue[i % 7] > 50) {
//and this is the line that controls LED colors as well as determining how bright
leds_value = CHSV((i / 6) * 32, 255, spectrumValue[i / 6]);
leds[i] = leds_value;
leds[NUM_LEDS - i] = leds_value;
}
for (int i = 238; i < NUM_LEDS / 2 - 1 < 392; i++) {
//this line is to get rid of background noise, change it higher if there is more noise
if (spectrumValue[i % 7] > 50) {
//and this is the line that controls LED colors as well as determining how bright
leds_value = CHSV((i / 11) * 32, 255, spectrumValue[i / 11]);
leds[i] = leds_value;
leds[NUM_LEDS - i] = leds_value;
}
//And to fade them out gently if no further input
leds[i].fadeToBlackBy(8);
}
FastLED.show();
}
|
#
?
Oct 6, 2015 05:39
|
|
- Captain Cool
- Oct 23, 2004
-
This is a song about messin' with people who've been messin' with you
|
code: for (int i = 0; i < NUM_LEDS / 2 - 1 < 154; i++)
for (int i = 154; i < NUM_LEDS / 2 - 1 < 238; i++)
for (int i = 238; i < NUM_LEDS / 2 - 1 < 392; i++)
These lines are not going to do what you want. You want one loop from 0 to 76, one from 154 to one ninety something, and one from 238 to 320 or so. Inside those loops you need to change the last assignment from NUM_LEDS-i to something that covers the gaps (77-153, 19x-237, 32x-392).
|
#
?
Oct 6, 2015 19:21
|
|
- dirtycajun
- Aug 27, 2004
-
SUCKING DICKS AND SQUEEZING TITTIES
|
Okay before I address that part I am still getting an error:
error: cannot convert 'CHSV' to 'int' in assignment
NM, Captain Cool figured it out. Back to the assigning of the strands.
dirtycajun fucked around with this message at 02:47 on Oct 7, 2015
|
#
?
Oct 7, 2015 02:20
|
|
- Parts Kit
- Jun 9, 2006
-
durr
i have a hole in my head
durr
|
I think you might have an extra bracket in the end, or be lacking one earlier in the program. Towards the end there's a } I can't find the { for.
Also none of those for loops are nested right? Seems like a bad idea to the same int variable for a bunch of different loops though I guess you could get away with it as long as they aren't nested.
|
#
?
Oct 7, 2015 04:36
|
|
- dirtycajun
- Aug 27, 2004
-
SUCKING DICKS AND SQUEEZING TITTIES
|
So working on it like this then:
code://Libraries
#include "FastLED.h"
int analogPin = 0; // MSGEQ7 OUT
int strobePin = 2; // MSGEQ7 STROBE
int resetPin = 4; // MSGEQ7 RESET
int spectrumValue[7];
int filterValue = 80;
#define NUM_LEDS 392
#define DATA_PIN 6
CRGB leds[NUM_LEDS];
CRGB leds_value;
void setup() {
Serial.begin(9600);
pinMode(analogPin, INPUT);
pinMode(strobePin, OUTPUT);
pinMode(resetPin, OUTPUT);
analogReference(DEFAULT);
digitalWrite(resetPin, LOW);
digitalWrite(strobePin, HIGH);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}
void loop()
{
digitalWrite(resetPin, HIGH);
digitalWrite(resetPin, LOW);
for (int i = 0; i < 7; i++)
{
digitalWrite(strobePin, LOW);
delayMicroseconds(30); // Allow output to settle
spectrumValue[i] = analogRead(analogPin);
spectrumValue[i] = constrain(spectrumValue[i], filterValue, 1023);
spectrumValue[i] = map(spectrumValue[i], filterValue, 1023, 0, 255);
Serial.print(spectrumValue[i]);
Serial.print(" ");
digitalWrite(strobePin, HIGH);
}
Serial.println();
// LEDs 1-154
for (int i = 0; i < (NUM_LEDS - 238) / 2 - 1; i++) {
if (spectrumValue[i % 7] > 50) {
leds_value = CHSV((i / 11) * 32, 255, spectrumValue[i / 11]);
leds[i] = leds_value;
leds[NUM_LEDS - i - 238] = leds_value;
}
leds[i].fadeToBlackBy(8);
}
// LEDs 155-238
for (int i = 154; i < NUM_LEDS / 2 - 1; i++) {
if (spectrumValue[i % 7] > 50) {
leds_value = CHSV((i / 6) * 32, 255, spectrumValue[i / 6]);
leds[i] = leds_value;
leds[NUM_LEDS - i] = leds_value;
}
leds[i].fadeToBlackBy(8);
}
// LEDs 239-392
for (int i = 238; i < (NUM_LEDS + 238) / 2 - 1; i++) {
if (spectrumValue[i % 7] > 50) {
leds_value = CHSV((i / 11) * 32, 255, spectrumValue[i / 11]);
leds[i] = leds_value;
leds[NUM_LEDS - i + 238] = leds_value;
}
leds[i].fadeToBlackBy(8);
}
FastLED.show();
}
Do I need to have the " leds[i].fadeToBlackBy(8);" in there three times or can I just run it once at the end?
|
#
?
Oct 7, 2015 04:40
|
|
- Captain Cool
- Oct 23, 2004
-
This is a song about messin' with people who've been messin' with you
|
So working on it like this then:
Looks okay. Does it work? I get nervous when I see things like "i+238" in an array index, but I think the math works out in this case.
quote:Do I need to have the " leds[i].fadeToBlackBy(8);" in there three times or can I just run it once at the end?
You need to run it on each LED, right? Then you'll also need to call it with leds[NUM_LEDS-i...].
|
#
?
Oct 7, 2015 14:21
|
|
- dirtycajun
- Aug 27, 2004
-
SUCKING DICKS AND SQUEEZING TITTIES
|
Okay, so the final question in the three part marathon of questions:
I set this up simply using only one MSGEQ7 in the code so far, but in reality it uses two of them in a Left Right RCA input. One stand will display LEDs for the instruments on the right including the theremin and the other the instruments on the left. The theremin stand will display the average of the two inputs.
At what point do I add something along the lines of "(spectrumValueRight + spectrumValueLeft) / 2 = spectrumValueMid" and is that how I would go about averaging those two values so that I have an average on the middle stand?
code://Libraries
#include "FastLED.h"
int analogPinR = 0; // MSGEQ7 Right OUT
int analogPinL = 1; // MSGEQ7 Left OUT
int strobePinR = 2; // MSGEQ7 Right STROBE
int strobePinL = 3; // MSGEQ7 Left STROBE
int resetPinR = 4; // MSGEQ7 Right RESET
int resetPinL = 5; // MSGEQ7 Left Reset
int spectrumValueRight[7];
int spectrumValueLeft[7];
int spectrumValueMid[7];
int filterValue = 80;
#define NUM_LEDS 392
#define DATA_PIN 6
CRGB leds[NUM_LEDS];
CRGB leds_value;
void setup() {
Serial.begin(9600);
pinMode(analogPinR, INPUT);
pinMode(analogPinL, INPUT);
pinMode(strobePinR, OUTPUT);
pinMode(strobePinL, OUTPUT);
pinMode(resetPinR, OUTPUT);
pinMode(resetPinL, OUTPUT);
analogReference(DEFAULT);
digitalWrite(resetPinR, LOW);
digitalWrite(resetPinL, LOW);
digitalWrite(strobePinR, HIGH);
digitalWrite(strobePinL, HIGH);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}
void loop()
{
digitalWrite(resetPinR, HIGH);
digitalWrite(resetPinL, HIGH);
digitalWrite(resetPinR, LOW);
digitalWrite(resetPinL, LOW);
for (int i = 0; i < 7; i++)
{
digitalWrite(strobePinR, LOW);
digitalWrite(strobePinL, LOW);
delayMicroseconds(30); // Allow output to settle
spectrumValueRight[i] = analogRead(analogPinR);
spectrumValueLeft[i] = analogRead(analogPinL);
spectrumValueRight[i] = constrain(spectrumValueRight[i], filterValue, 1023);
spectrumValueLeft[i] = constrain(spectrumValueLeft[i], filterValue, 1023);
spectrumValueRight[i] = map(spectrumValueRight[i], filterValue, 1023, 0, 255);
spectrumValueLeft[i] = map(spectrumValueLeft[i], filterValue, 1023, 0, 255);
Serial.print(spectrumValueRight[i]);
Serial.print(spectrumValueLeft[i]);
Serial.print(" ");
digitalWrite(strobePinR, HIGH);
digitalWrite(strobePinL, HIGH);
}
Serial.println();
// LEDs 1-154
for (int i = 0; i < (NUM_LEDS - 238) / 2 - 1; i++) {
if (spectrumValueRight[i % 7] > 50) {
leds_value = CHSV((i / 11) * 32, 255, spectrumValueRight[i / 11]);
leds[i] = leds_value;
leds[NUM_LEDS - i - 238] = leds_value;
}
leds[i].fadeToBlackBy(8);
leds[NUM_LEDS - i - 238].fadeToBlackBy(8);
}
// LEDs 155-238
for (int i = 154; i < NUM_LEDS / 2 - 1; i++) {
if (spectrumValueMid[i % 7] > 50) {
leds_value = CHSV((i / 6) * 32, 255, spectrumValueMid[i / 6]);
leds[i] = leds_value;
leds[NUM_LEDS - i] = leds_value;
}
leds[i].fadeToBlackBy(8);
leds[NUM_LEDS - i].fadeToBlackBy(8);
}
// LEDs 239-392
for (int i = 238; i < (NUM_LEDS + 238) / 2 - 1; i++) {
if (spectrumValueLeft[i % 7] > 50) {
leds_value = CHSV((i / 11) * 32, 255, spectrumValueLeft[i / 11]);
leds[i] = leds_value;
leds[NUM_LEDS - i + 238] = leds_value;
}
leds[i].fadeToBlackBy(8);
leds[NUM_LEDS - i + 238].fadeToBlackBy(8);
}
FastLED.show();
}
dirtycajun fucked around with this message at 04:31 on Oct 8, 2015
|
#
?
Oct 8, 2015 04:18
|
|
- Captain Cool
- Oct 23, 2004
-
This is a song about messin' with people who've been messin' with you
|
What's the easiest (and reasonably pin efficient) way to drive, say, three single digit 7 segment displays? Will I need a separate driver (i.e. MAX7219) for each digit? It seems like the four digit, 7 segment displays can be driven by just one driver.
I haven't pulled up any chip datasheets, but here's someone who was doing the same thing recently: http://forums.somethingawful.com/showthread.php?threadid=2734977&userid=124396#post447466792
Okay, so the final question in the three part marathon of questions:
I set this up simply using only one MSGEQ7 in the code so far, but in reality it uses two of them in a Left Right RCA input. One stand will display LEDs for the instruments on the right including the theremin and the other the instruments on the left. The theremin stand will display the average of the two inputs.
At what point do I add something along the lines of "(spectrumValueRight + spectrumValueLeft) / 2 = spectrumValueMid" and is that how I would go about averaging those two values so that I have an average on the middle stand?
Right after you get the final values for left and right:
quote:code: spectrumValueRight[i] = map(spectrumValueRight[i], filterValue, 1023, 0, 255);
spectrumValueLeft[i] = map(spectrumValueLeft[i], filterValue, 1023, 0, 255);
|
#
?
Oct 8, 2015 05:00
|
|
- mod sassinator
- Dec 13, 2006
-
I came here to Kick Ass and Chew Bubblegum,
and I'm All out of Ass
|
And in the code constantly read the input pin for the button and look for a low -> high level transition. That only occurs the exact moment the button is released (when the button is pressed the input is pulled down to ground, then when released the pull-up will pull it back up to a high level). If you test for that transition from low to high then you'll easily catch the button being released. Do something like:
code:// Take two readings for the button input, add a small delay to catch the low to high transition.
bool first = digitalRead(BUTTON_PIN);
delay(10);
bool second = digitalRead(BUTTON_PIN);
// Check if the first is low and the second is high, that means the button was released.
if (!first && second) {
// Button was released! Do stuff here.
}
// Be careful in the rest of your loop not to spend too much time or else the two reading check above might miss the low -> high transition.
|
#
?
Oct 8, 2015 17:23
|
|
- TheresaJayne
- Jul 1, 2011
-
|
I have been having problems with a sketch i have been working on, I don't know yet whether it is bad wiring (using a breadboard) or bad logic in the sketch
The plan was to have a trigger so closing the lid of a box would trigger the servo to move to the lock position.
Then even though the lock button is pressed, when the unlock button / reed sensor is triggered it will unlock the servo for 30 seconds before resetting and if the lid is still closed relock the box.
But it locks and will not unlock until i release the lock button which is not the functionality i need.
code:
Servo servo;
boolean locker;
int servoPos;
int pinRead;
void setup()
{
locker = false;
pinMode(1,INPUT);
pinMode(2,INPUT);
servo.attach(9);
servoPos = 0;
servo.write(servoPos); //Set to unlock position
}
void loop()
{
if(locker == false)
{
pinRead = digitalRead(1);
if (pinRead == HIGH)
{
servoPos = 180;
locker = true;
servo.write(servoPos);
}
}
else
{
pinRead = digitalRead(2);
if(pinRead == HIGH)
{
servoPos = 0;
servo.write(servoPos);
delay(20000);
}
}
}
|
#
?
Oct 12, 2015 08:17
|
|
- Deanut Pancer
- Nov 24, 2012
-
|
Looks like you're missing a "locker = false;" assignment just after the "delay(20000);" statement?
|
#
?
Oct 12, 2015 23:49
|
|
- TheresaJayne
- Jul 1, 2011
-
|
Looks like you're missing a "locker = false;" assignment just after the "delay(20000);" statement?
Actually my plan currently is to get it working where you have to reset to get it to relock,
The problem is that button 2 never works if button 1 is down
|
#
?
Oct 13, 2015 07:20
|
|
- Combat Pretzel
- Jun 23, 2004
-
No, seriously... what kurds?!
|
A friend of mine asked me, whether I can implement some coin counter, that counts coins per session, total and an average per hour. I figured I'll get an Arduino starter kit (and tinker with it). Question is, the IR sender and receiver in these kits, they're essentially just a LED and a photodiode that I can just go use as a lightbarrier instead, right?
|
#
?
Oct 13, 2015 15:46
|
|
- Parts Kit
- Jun 9, 2006
-
durr
i have a hole in my head
durr
|
I don't think so, I think those are more like the stuff in a tv remote control? But there are optical switches that would do that at a low cost. If you go for optical switches be sure to read the specs carefully as they come with different channel widths and heights, and some of them are not going to be useful for something as 'fat' as a coin.
Another easy option would be a microswitch without a roller on the lever. A coin going down a chute should have more than enough force to click it and keep moving out of the way so it resets. Might put more of a limit how fast you can run coins in though.
|
#
?
Oct 13, 2015 17:05
|
|
- Captain Cool
- Oct 23, 2004
-
This is a song about messin' with people who've been messin' with you
|
Actually my plan currently is to get it working where you have to reset to get it to relock,
The problem is that button 2 never works if button 1 is down
How are your buttons connected? Also, if you want some action to happen after the 20 second delay, you need some code there. Otherwise, as written, the delay doesn't matter because the loop can't do anything after that point.
A friend of mine asked me, whether I can implement some coin counter, that counts coins per session, total and an average per hour. I figured I'll get an Arduino starter kit (and tinker with it). Question is, the IR sender and receiver in these kits, they're essentially just a LED and a photodiode that I can just go use as a lightbarrier instead, right?
Do you really need to implement your own sensor? If this is for an arcade machine or something you should be able to tap into the "coin inserted" signal that's already present.
|
#
?
Oct 13, 2015 18:36
|
|
- Subyng
- May 4, 2013
-
|
Can someone recommend me a retailer where I can buy misc mechanical parts like gears and such? Either online or if you're in the Greater Toronto Area, a physical store? Hobby shops seem to only have parts that are part of kits. At this point I'm thinking it might be easier to just buy some Lego technic pieces and adapt them to my servo.
Speaking of which, I'm trying to build a very simple "finger" which really just needs to be a rigid bar that rotates. The problem is I need to have the axis of rotation of the finger 90 degrees to the output shaft of my servo (I can't just rotate the entire motor). I'm thinking of just using 2 bevel gears 90 degrees apart, one on the servo shaft and the other in the finger. Is there an easier way to do this from a mechanical perspective or just in terms of acquiring the necessary parts?
|
#
?
Oct 13, 2015 19:20
|
|
- Combat Pretzel
- Jun 23, 2004
-
No, seriously... what kurds?!
|
Do you really need to implement your own sensor? If this is for an arcade machine or something you should be able to tap into the "coin inserted" signal that's already present.
Lazy person scenario. He's in some carnival society and they're frequently hosting parties. Drinks are a voucher or plastic coin each, and these are bought at the entrance. Sounds stupid, but when the beer price is 1.30€, it's easier to sell plastic coins in bulk than fiddle with change all the time. They've been throwing the coins into a bucket and count them the day after. He wants to know the count and optional ancillary stats (beer per hour) immediately, thus a custom coin counter with a light barrier.
I suppose a regular LED and photodiode should cut it, too, when enclosed and sufficiently shielded from external light sources? I'd need to calibrate the Schmitt trigger I want to use on the analog input first, anyway (I've already seen basic schematics for an Arduino counter with a lightbarrier).
|
#
?
Oct 13, 2015 19:32
|
|
- dirtycajun
- Aug 27, 2004
-
SUCKING DICKS AND SQUEEZING TITTIES
|
So I have built the beast and implemented the code, unfortunately it looks like my serial monitor is going nuts with zero input from my end and it's doing all kinds of crazy poo poo with the LEDs, but only the first strand (might be a construction error) Any idea on what's going on?
code://Libraries
#include "FastLED.h"
int analogPinR = 0; // MSGEQ7 Right OUT
int analogPinL = 1; // MSGEQ7 Left OUT
int strobePinR = 2; // MSGEQ7 Right STROBE
int strobePinL = 3; // MSGEQ7 Left STROBE
int resetPinR = 4; // MSGEQ7 Right RESET
int resetPinL = 5; // MSGEQ7 Left Reset
int spectrumValueRight[7];
int spectrumValueLeft[7];
int spectrumValueMid[7];
int filterValue = 80;
#define NUM_LEDS 392
#define DATA_PIN 6
CRGB leds[NUM_LEDS];
CRGB leds_value;
void setup() {
Serial.begin(9600);
pinMode(analogPinR, INPUT);
pinMode(analogPinL, INPUT);
pinMode(strobePinR, OUTPUT);
pinMode(strobePinL, OUTPUT);
pinMode(resetPinR, OUTPUT);
pinMode(resetPinL, OUTPUT);
analogReference(DEFAULT);
digitalWrite(resetPinR, LOW);
digitalWrite(resetPinL, LOW);
digitalWrite(strobePinR, HIGH);
digitalWrite(strobePinL, HIGH);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}
void loop()
{
digitalWrite(resetPinR, HIGH);
digitalWrite(resetPinL, HIGH);
digitalWrite(resetPinR, LOW);
digitalWrite(resetPinL, LOW);
for (int i = 0; i < 7; i++)
{
digitalWrite(strobePinR, LOW);
digitalWrite(strobePinL, LOW);
delayMicroseconds(30); // Allow output to settle
spectrumValueRight[i] = analogRead(analogPinR);
spectrumValueLeft[i] = analogRead(analogPinL);
spectrumValueRight[i] = constrain(spectrumValueRight[i], filterValue, 1023);
spectrumValueLeft[i] = constrain(spectrumValueLeft[i], filterValue, 1023);
spectrumValueRight[i] = map(spectrumValueRight[i], filterValue, 1023, 0, 255);
spectrumValueLeft[i] = map(spectrumValueLeft[i], filterValue, 1023, 0, 255);
spectrumValueMid[i] = (spectrumValueRight[i] + spectrumValueLeft[i]) / 2;
Serial.print(spectrumValueRight[i]);
Serial.print(spectrumValueLeft[i]);
Serial.print(" ");
digitalWrite(strobePinR, HIGH);
digitalWrite(strobePinL, HIGH);
}
Serial.println();
// LEDs 1-154
for (int i = 0; i < (NUM_LEDS - 238) / 2 - 1; i++) {
leds_value = CHSV((i / 11) * 32, 255, spectrumValueRight[i / 11]);
leds[i] = leds_value;
leds[NUM_LEDS - i - 238] = leds_value;
leds[i].fadeToBlackBy(8);
leds[NUM_LEDS - i - 238].fadeToBlackBy(8);
}
// LEDs 155-238
for (int i = 154; i < NUM_LEDS / 2 - 1; i++) {
leds_value = CHSV((i / 6) * 32, 255, spectrumValueMid[i / 6]);
leds[i] = leds_value;
leds[NUM_LEDS - i] = leds_value;
leds[i].fadeToBlackBy(8);
leds[NUM_LEDS - i].fadeToBlackBy(8);
}
// LEDs 239-392
for (int i = 238; i < (NUM_LEDS + 238) / 2 - 1; i++) {
leds_value = CHSV((i / 11) * 32, 255, spectrumValueLeft[i / 11]);
leds[i] = leds_value;
leds[NUM_LEDS - i + 238] = leds_value;
leds[i].fadeToBlackBy(8);
leds[NUM_LEDS - i + 238].fadeToBlackBy(8);
}
FastLED.show();
}
from the serial monitor:
2020 1919 1818 1918 1818 1717 1817
1918 1818 1717 1817 1717 1716 1716
1818 1817 1716 1717 1716 1615 1616
|
#
?
Oct 14, 2015 01:14
|
|
- ThinkFear
- Sep 15, 2007
-
|
Lazy person scenario. He's in some carnival society and they're frequently hosting parties. Drinks are a voucher or plastic coin each, and these are bought at the entrance. Sounds stupid, but when the beer price is 1.30€, it's easier to sell plastic coins in bulk than fiddle with change all the time. They've been throwing the coins into a bucket and count them the day after. He wants to know the count and optional ancillary stats (beer per hour) immediately, thus a custom coin counter with a light barrier.
I suppose a regular LED and photodiode should cut it, too, when enclosed and sufficiently shielded from external light sources? I'd need to calibrate the Schmitt trigger I want to use on the analog input first, anyway (I've already seen basic schematics for an Arduino counter with a lightbarrier).
I know this is the arduino thread, but don't over complicate it. China grade panel mount counter and capacitive prox, done for under $20 and even fewer minutes.
|
#
?
Oct 14, 2015 01:16
|
|
- Captain Cool
- Oct 23, 2004
-
This is a song about messin' with people who've been messin' with you
|
So I have built the beast and implemented the code, unfortunately it looks like my serial monitor is going nuts with zero input from my end and it's doing all kinds of crazy poo poo with the LEDs, but only the first strand (might be a construction error) Any idea on what's going on?
Do the values on serial look right? You're expecting them to vary with sound, right? Do they?
To debug a physical error, comment out your three LED loops and replace them with a single loop that just sets all LEDs to an arbitrary value.
|
#
?
Oct 14, 2015 03:41
|
|
- dirtycajun
- Aug 27, 2004
-
SUCKING DICKS AND SQUEEZING TITTIES
|
Do the values on serial look right? You're expecting them to vary with sound, right? Do they?
To debug a physical error, comment out your three LED loops and replace them with a single loop that just sets all LEDs to an arbitrary value.
No those are values that are occurring with no input.
|
#
?
Oct 14, 2015 08:35
|
|
- dirtycajun
- Aug 27, 2004
-
SUCKING DICKS AND SQUEEZING TITTIES
|
Small project till I finish work on the main one tomorrow and tuesday.
I built the drum lights gemma project for my roommate's kickdrum a bit ago but it's way too (basically any noise will set it off) sensitive. Looking at the code below how do I turn down the sensitivity.
EDIT: actually gently caress most of this. He just wants all the LEDs to shine for a half second and then turn off until summoned again. Please help me gut this code (mostly I need to know how to use the mic input better)
code:/* LED "Color Organ" for Adafruit Trinket and NeoPixel LEDs.
Hardware requirements:
- Adafruit Trinket or Gemma mini microcontroller (ATTiny85).
- Adafruit Electret Microphone Amplifier (ID: 1063)
- Several Neopixels, you can mix and match
o Adafruit Flora RGB Smart Pixels (ID: 1260)
o Adafruit NeoPixel Digital LED strip (ID: 1138)
o Adafruit Neopixel Ring (ID: 1463)
Software requirements:
- Adafruit NeoPixel library
Connections:
- 5 V to mic amp +
- GND to mic amp -
- Analog pinto microphone output (configurable below)
- Digital pin to LED data input (configurable below)
Written by Adafruit Industries. Distributed under the BSD license.
This paragraph must be included in any redistribution.
*/
#include <Adafruit_NeoPixel.h>
#define N_PIXELS 60 // Number of pixels you are using
#define MIC_PIN 1 // Microphone is attached to Trinket GPIO #2/Gemma D2 (A1)
#define LED_PIN 0 // NeoPixel LED strand is connected to GPIO #0 / D0
#define DC_OFFSET 0 // DC offset in mic signal - if unusure, leave 0
#define NOISE 100 // Noise/hum/interference in mic signal
#define SAMPLES 60 // Length of buffer for dynamic level adjustment
#define TOP (N_PIXELS +1) // Allow dot to go slightly off scale
// Comment out the next line if you do not want brightness control or have a Gemma
#define POT_PIN 3 // if defined, a potentiometer is on GPIO #3 (A3, Trinket only)
byte
peak = 0, // Used for falling dot
dotCount = 0, // Frame counter for delaying dot-falling speed
volCount = 0; // Frame counter for storing past volume data
int
vol[SAMPLES], // Collection of prior volume samples
lvl = 10, // Current "dampened" audio level
minLvlAvg = 0, // For dynamic adjustment of graph low & high
maxLvlAvg = 512;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
memset(vol, 0, sizeof(vol));
strip.begin();
}
void loop() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN); // Raw reading from mic
n = abs(n - 512 - DC_OFFSET); // Center on zero
n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum
lvl = ((lvl * 7) + n) >> 3; // "Dampened" reading (else looks twitchy)
// Calculate bar height based on dynamic min/max levels (fixed point):
height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if(height < 0L) height = 0; // Clip output
else if(height > TOP) height = TOP;
if(height > peak) peak = height; // Keep 'peak' dot at top
// if POT_PIN is defined, we have a potentiometer on GPIO #3 on a Trinket
// (Gemma doesn't have this pin)
uint8_t bright = 255;
#ifdef POT_PIN
bright = analogRead(POT_PIN); // Read pin (0-255) (adjust potentiometer
// to give 0 to Vcc volts
#endif
strip.setBrightness(bright); // Set LED brightness (if POT_PIN at top
// define commented out, will be full)
// Color pixels based on rainbow gradient
for(i=0; i<N_PIXELS; i++) {
if(i >= height)
strip.setPixelColor(i, 0, 0, 0);
else
strip.setPixelColor(i,Wheel(map(i,0,strip.numPixels()-1,30,150)));
}
strip.show(); // Update strip
vol[volCount] = n; // Save sample for dynamic leveling
if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter
// Get volume range of prior frames
minLvl = maxLvl = vol[0];
for(i=1; i<SAMPLES; i++) {
if(vol[i] < minLvl) minLvl = vol[i];
else if(vol[i] > maxLvl) maxLvl = vol[i];
}
// minLvl and maxLvl indicate the volume range over prior frames, used
// for vertically scaling the output graph (so it looks interesting
// regardless of volume level). If they're too close together though
// (e.g. at very low volume levels) the graph becomes super coarse
// and 'jumpy'...so keep some minimum distance between them (this
// also lets the graph go to zero when no sound is playing):
if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
dirtycajun fucked around with this message at 23:15 on Oct 18, 2015
|
#
?
Oct 18, 2015 23:03
|
|
- DreadLlama
- Jul 15, 2005
-
Not just for breakfast anymore
|
edit: re-read op. Am dumb. Nevermind.
DreadLlama fucked around with this message at 05:00 on Oct 19, 2015
|
#
?
Oct 19, 2015 04:49
|
|
- Captain Cool
- Oct 23, 2004
-
This is a song about messin' with people who've been messin' with you
|
No those are values that are occurring with no input.
0 gets constrained to 80 which gets mapped to 20 which starts fading.
Actually, now that I look at it, your fade call isn't really going to do anything useful. You're using fresh values for all LEDs each time through. If you want them to fade out on no input, you need to detect the low input and not set those lights to any new value that time through the loop.
EDIT: actually gently caress most of this. He just wants all the LEDs to shine for a half second and then turn off until summoned again. Please help me gut this code (mostly I need to know how to use the mic input better)
If the mic read is high, turn on the lights and reset a timeout time to millis() + 500. If millis() passes the timeout time, turn the lights off.
|
#
?
Oct 19, 2015 04:59
|
|
- dirtycajun
- Aug 27, 2004
-
SUCKING DICKS AND SQUEEZING TITTIES
|
0 gets constrained to 80 which gets mapped to 20 which starts fading.
Actually, now that I look at it, your fade call isn't really going to do anything useful. You're using fresh values for all LEDs each time through. If you want them to fade out on no input, you need to detect the low input and not set those lights to any new value that time through the loop.
If the mic read is high, turn on the lights and reset a timeout time to millis() + 500. If millis() passes the timeout time, turn the lights off.
The map doing that makes a lot of sense thank you.
|
#
?
Oct 19, 2015 13:05
|
|
- Adbot
-
ADBOT LOVES YOU
|
|
#
?
May 31, 2024 22:16
|
|