2 questions - DC motor and Neopixels

Hi, I am a newbie but have been reading as much as I can and still have two issues.

I am currently working on my graduation project where I need to create a swimming leech that lights up. The idea is that the leech responds to hormones in blood and displays the emotions of its prey through it’s bioluminescent skin (in case you were wondering…)

I am using a trinket pro 5V, a L293D motor controller, a DC motor, and RGB sewable neopixels (trying to keep it small to stick inside my ecoflex leech model)

I am working on two separate sketches right now - getting each one to work on it’s own before combining them. Also, in case this comes up, I was told to use a DC motor instead of a servo because the physical resistance of the leech tail might be too much for the servo to turn.

Here are my requirements:

motor:
I need the tail to ''swish" back and forth
the tail “swish” will have a low and a high speed
the low speed and high speed will be enacted at random times, for believability

lights:
need the lights to cycle rainbow colours
lights stop on random colours for 5 seconds before returning to rainbow cycle.

I have been able to do almost all of this! my problems are:

  1. motor: When I try to add a random delay between the low speed and high speed swish, the motor only spins in one direction for each speed setting, instead of back and forth. It does switch directions and speed (spins on high in one direction for a random time, spins on low in the other direction for a random time), but I lose the swish!

  2. neopixel: The rainbow cycler is fine, the random delay is fine, the pausing on a colour is fine, BUT it always pauses on red - the color needs to be random every time.

Any help is very much appreciated! Please let me know if I am missing any crucial bits that will help people understand my problem. Thank you!

motor code:

#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// using Trinket Pro 5V, DC motor, L293D motor driver

int speedPin = 5;
int dir1 = 4;
int dir2 = 3;
int hSpeed = 200;
int lSpeed = 80;

void setup() {
  // put your setup code here, to run once:
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  pinMode(speedPin, OUTPUT);
  pinMode(dir1, OUTPUT);
  pinMode(dir2, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

  lowFlip(); //DC motor moves back and forth, lower speed

  delay(random(1000, 10000)); //lowFlip operates for a random amount of time up to 10 seconds

  highFlip(); //DC motor moves back and forth, lower speed

  delay(random(1000, 3000)); //lowFlip operates for a random amount of time up to 3 seconds

}



void highFlip() {
  digitalWrite(dir1, LOW); //clockwise
  digitalWrite(dir2, HIGH);
  analogWrite(speedPin, 100); //speed to jumpstart motor
  delay(10);
  analogWrite(speedPin, hSpeed);
  delay(75);


  digitalWrite(dir1, HIGH); //counterclockwise
  digitalWrite(dir2, LOW);
  analogWrite(speedPin, 100); //speed to jumpstart motor
  delay(10);
  analogWrite(speedPin, hSpeed);
  delay(75);
}


void lowFlip() {
  digitalWrite(dir1, LOW); //clockwise
  digitalWrite(dir2, HIGH);
  analogWrite(speedPin, 100); //speed to jumpstart motor
  delay(10);
  analogWrite(speedPin, lSpeed);
  delay(75);


  digitalWrite(dir1, HIGH); //counterclockwise
  digitalWrite(dir2, LOW);
  analogWrite(speedPin, 100); //speed to jumpstart motor
  delay(10);
  analogWrite(speedPin, lSpeed);
  delay(75);
}

Neopixel code:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    6

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 1


// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


// setup() function -- runs once at startup --------------------------------

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)

}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop() {


  rainbow(10);             // Flowing rainbow cycle along the whole strip


  delay(random(1000, 10000)); // run rainbow cycle for 1-10 seconds

  strip.setPixelColor(0, random(255), random(255), random(255)); //stop colour cycling on random colour


  delay(5000); //show pixel color for 5 seconds before returning to rainbow cycle

}


// Some functions of our own for creating animated effects -----------------



// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this outer loop:
  for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {
    for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

You are up to a very delicate project. There's a lot of high level science involved.
Sort things out: "Swimming leech". What on earth would that be?

Making motors run, neopixels.... no problem.

Impressive, You are on the right way of system integration, first making the sub systems work and then integrating them.

Random delay.... What is the random event? Direction or speed? Maybe speed. Your test code should be spinning CW for some seconds, then CCw for some seconds. Does that work?

Please post a wiring showing the powering, names of connection points of all devices. You can't imagine how often this basic things are creating trouble.

Question 2 ought to be seen in Your code, but it's too late to dig down in the code.

Thanks for the quick reply - schematics are attached!

For the random delay with the motor, I made a function where I have that CW/CCW switch that happens at a certain speed and it works on it's own - I want that function that includes the back and forth to run for a random amount of seconds before moving to the next function that is a higher speed function of the same CW/CCW motion. Maybe I'm using the wrong wording? Do I need to put the function into a loop and use a delay after that? hmm

For the neopixel, I think my issue is something here:
strip.setPixelColor(0, random(255), random(255), random(255)); //stop colour cycling on random colour
I thought that this meant that the first neopixel will set to a random R, G, and B value but it only stops on red, every time.

Thanks for a good try. I magnified You drawing to 500% but can't still read pin designations etc. The contrast is too low.

I see "battery". That is not good enough. You don't know how often "battery" is totally inadequate.....

You have issues with the motor. Have a look into Arduino/reference regarding random. Random delay, random speed, random direction... I'm way too late to go into deeper code analysis.

The neopixels... Again, take a good look at how the function "random" works. Check what the input variable does and what You receive. I've never used it....

Stopps on red.... That's a simple code issue.

Cheers and good night, until tomorrow.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.