Go Down

Topic: Arduino Program Stop Working after 1 sec (Read 224 times) previous topic - next topic

yacine1991

I have a program that is supposed to turn on 4 LEDs simultaneously in 4 steps:

the 4 LEDs are turned on for 500 ms using PMW for a value of 10mv.
the 4 LEDs are turned on for 500 ms using PMW for a value of 250mv.
the 4 LEDs are turned on for 500 ms using PMW for a value of 50mv.
the 4 LEDs are turned on for 500 ms using PMW for a value of 0mv.
The program makes the stpe 1 and 2 and then it stops wotking and the LEDs keep on at 250mv.

I tried to change the duration for the first two steps but it always stops after these first two steps are done and don't continue the 3 and 4.

I used oriented object programming so please be patient with the code; actually the most important classes are Effect and Motor.

Node.cpp: this class creates a Node which is defined by an amplitude and a duration for the selected for example: amplitude: 10mv duration:500ms


Code: [Select]
#include "Arduino.h"
#include "Node.h"

Node::Node(){}
Node::~Node(){}

int Node::getAmplitude()
    {
    return  _amplitude;
    }

unsigned long Node::getDuration()
    {
    return  _duration;
    }

void Node::setPatternNode(int amplitude,unsigned long duration)
    {
    _amplitude=amplitude;
    _duration=duration;
    }


Pattern.cpp : this class creates an array of Nodes created initially to result in a particular pattern of vibration for example: amplitude{10,250,50,0} duration{500,500,500,500}

Code: [Select]
#include "Arduino.h"
#include "Pattern.h"
#include "Node.h"
#include "QueueArray.h"
#include "Motor.h"

Pattern::Pattern(){}
Pattern::~Pattern(){}

QueueArray <Node> Pattern::setPattern(int amplitude[4],unsigned long duration[4]){
    QueueArray <Node> queue;
    unsigned long nodeDurationSum = 0;
    for (int i=0;i<4;i++){
    Node node;
    nodeDurationSum = nodeDurationSum + duration[i]; //the reference for duration calculation is patternStartTime
    node.setPatternNode(amplitude[i],nodeDurationSum);
    queue.enqueue(node);
    }
    return queue;
}


Motor.cpp: this class affects the pattern(s) created by the class Pattern to the selected motor(s).

Code: [Select]
#include "Arduino.h"
#include "Motor.h"
#include "QueueArray.h"
#include "Node.h"
#include "Pattern.h"


Motor::Motor()
    {
    }

Motor::Motor(int pin)
    {
        pinMode(pin, OUTPUT);
        _pin = pin;
    }

Motor::~Motor()
    {
    }


    void Motor::runMotor()
    {
        if(_isMotorActive){
        _currentTime=millis();//_currentTime is declared as "unsigned long"
        Serial.println(_currentTime);       
        if(_currentTime < _currentNode.getDuration())
            {
            analogWrite(_pin,_currentNode.getAmplitude());
            }
        else
            {
            if(_currentPattern.isEmpty())
               {
                _isMotorActive = false;
               }
             updateCurrentNode();
            }

        }

    }


    void Motor::motorSetPattern(QueueArray <Node> p)
    {
    _currentPattern = p;
    _isMotorActive = true;
    _patternStartTime = millis();//_patternStartTime is declared as "unsigned long"
    updateCurrentNode();
    }

int Motor::getCurrentPatternLength()
    {
    return _currentPattern.count();
    }


void Motor::updateCurrentNode()
    {
    _currentNode = _currentPattern.dequeue();


Effect.cpp: this class run more than 1 motor, each motor is run following the Pattern to whom it is affected.

Code: [Select]
#include "Arduino.h"
#include "Effect.h"
#include "Motor.h"

Effect::Effect(){}

Effect::Effect(Motor m1,Motor m2,Motor m3,Motor m4,QueueArray <Node> p1,QueueArray <Node> p2,QueueArray <Node> p3,QueueArray <Node> p4)
    {
    _vibmotor1=m1;
    _vibmotor2=m2;
    _vibmotor3=m3;
    _vibmotor4=m4;

    _motorPattern1 = p1;
    _motorPattern2 = p2;
    _motorPattern3 = p3;
    _motorPattern4 = p4;

    _vibmotor1.motorSetPattern(_motorPattern1);
    _vibmotor2.motorSetPattern(_motorPattern2);
    _vibmotor3.motorSetPattern(_motorPattern3);
    _vibmotor4.motorSetPattern(_motorPattern4);
    }

Effect::~Effect()
    {
    }


void Effect::runEffect()
    {
    _vibmotor1.runMotor();
    _vibmotor2.runMotor();     
    _vibmotor3.runMotor();     
    _vibmotor4.runMotor();     
    }


And this is the arduino sketch:

Code: [Select]
#include <Effect.h>
#include <Motor.h>
#include <Node.h>
#include <Pattern.h>
#include <QueueArray.h>

Motor vibmotor1(3);
Motor vibmotor2(5);
Motor vibmotor3(6);
Motor vibmotor4(9);

Pattern pattern;

int amplitude1[4] = {10,250,50,0};
unsigned long duration1[4] = {500,500,500,500};
int amplitude2[4] = {10,250,50,0};
unsigned long duration2[4] = {500,500,500,500};
int amplitude3[4] = {10,250,50,0};
unsigned long duration3[4] = {500,500,500,500};
int amplitude4[4] = {10,250,50,0};
unsigned long duration4[4] = {500,500,500,500};

QueueArray <Node> p1 = pattern.setPattern(amplitude1,duration1);
QueueArray <Node> p2 = pattern.setPattern(amplitude2,duration2);
QueueArray <Node> p3 = pattern.setPattern(amplitude3,duration3);
QueueArray <Node> p4 = pattern.setPattern(amplitude4,duration4);

Effect effect1(vibmotor1,vibmotor2,vibmotor3,vibmotor4,p1,p2,p3,p4);

void setup()
{
Serial.begin(9600);



void loop()
{
   effect1.runEffect();

}

PaulS

Code: [Select]
Motor::Motor(int pin)
    {
        pinMode(pin, OUTPUT);
        _pin = pin;
    }

When is your constructor called? Before init()? Or after init()? If you don't know, don't diddle with the hardware in the constructor.

Code: [Select]
QueueArray <Node> Pattern::setPattern(int amplitude[4],unsigned long duration[4]){
    QueueArray <Node> queue;
    unsigned long nodeDurationSum = 0;
    for (int i=0;i<4;i++){
    Node node;
    nodeDurationSum = nodeDurationSum + duration[i]; //the reference for duration calculation is patternStartTime
    node.setPatternNode(amplitude[i],nodeDurationSum);
    queue.enqueue(node);
    }
    return queue;
}

What happens to the Node instance when this function ends? What effect does that have on the queued data?

This is really complicated, memory intensive code for use on a limited memory Arduino.

GoForSmoke


the 4 LEDs are turned on for 500 ms using PMW for a value of 10mv.
the 4 LEDs are turned on for 500 ms using PMW for a value of 250mv.
the 4 LEDs are turned on for 500 ms using PMW for a value of 50mv.
the 4 LEDs are turned on for 500 ms using PMW for a value of 0mv.


Unless you have a circuit to turn PWM into analog, it doesn't work that way.
PWM is full VCC for value/256 time out of each duty cycle.
Default duty cycle is about (just over) 2 ms. PWM 127 should get just over 1 ms ON, 1 ms OFF at 5V pattern.
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Grumpy_Mike

Quote
the 4 LEDs are turned on for 500 ms using PMW for a value of 0mv.

In what way is supplying an LED with 0 volts turning it on?
How do you turn them off then?

GoForSmoke

I thought for sure that a led has a minimum trigger voltage by color and a maximum voltage not much more.
Red led needs > 1V doesn't it?
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

yacine1991

it's not about the LED because even without the LEDs I can see the problem in Serial Monitor

GoForSmoke

My question was and is about what you seem to think some of the code is doing.
I don't know how that affects the whole but one good wrong assumption usually makes major problems.

I saw that and stopped right there and asked a question that you haven't bothered to answer at all.
I don't have your hardware setup to be able to find the answers myself either.

How much of that did you write before testing the first time?
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up