Why do I have to reset the Arduino?

Hi folks,

I want to add a simple display to my program to that will display the values of 2 variables constantly. Serial monitor is NOT an option, nor any Serial functions. They conflict with the mounted shield circuitry. If I put a Serial.begin(57600); This is what I get:

HardwareSerial0.cpp.o (symbol from plugin): In function `Serial':
(.text+0x0): multiple definition of `__vector_18'
/private/var/folders/95/3v77r_wn0bj93bx8dzfvjxs40000gp/T/arduino/sketches/4F0EEA3973E7A184D13B7B9DC1580383/libraries/Conceptinetics/Conceptinetics.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

I've looked around and all I can find is complicated code and circuitry. I have 2 values which are between 0 and 255. All I want to see is their values. Where can I find SIMPLE code to do this.

My second issue is that I need to be able to press the reset button on the Arduino. Is there circuitry to do this? I have my circuitry inside a project box and there is no easy way to get at the switch.

Thanks,

Joe B

What would you like to see them on - LCD, LED, Computer screen?
What Arduino product are you using?

Since there are only two values use the onboard LED. You can cycle the power to reset it or add an external reset circuit. I do not know your skill set or resources to I cannot offer much more.

I have a couple of LCD displays around, just need to find the docs. I'm using an Arduino UNO R3 knockoff (NOT the 240 chip).
Sorry about that, I am not looking for just 0 and 255, I am looking for values BETWEEN 0,255. My bad.

Thanks,

Joe B

ps My skill set is former Rocket Scientist. I have tons of parts laying around, just haven't been doing much Arduino for about 6 years. Since I'm old I forget a lot :slight_smile:

jb

reset pin and gnd pin are available on the 6-pin programming header, so you could just add jumpers from an external button to those two pins.

1 Like

For the LCD, if what you have is appropriate, you could buy an I2C adapter to ease the wiring.

I must question why you must manually reset the Arduino. Instead of finding a way to do that, time would be well spent fixing the reason that resets are required.

1 Like

Actually no. I have had this issue with this hardware for a couple of months. It got to the point where I got sponsored with "real" equipment but now I find myself needing to resurrect part of the system.
VERY LONG story short. I wrote a musical, couldn't afford actors, vocalists, a venue or the staging to do the musical. BUT I did have a lot of Legos. So I started building stages in the hopes of getting a contract with Lego. To compete I needed a SERIOUS camera dolly which I built from an old CNC machine (I mentored a local high school group in engineering and robotics), a couple of Arduinos from my stint as a DJ/VJ years ago and a DMX board. The software I use to shot Stop Frame Animation is Dragonframe which is an industry standard. It had a DMX component which I used to drive my camera. Enter HEAT, actually overheating of the stepper motors. I lost the date for submission to Lego. So I spoke to a company that supplied MOCO (Motion Control) systems for cameras to see if I could work out a payment plan. They graciously agreed to gift me a quite expensive MOCO system to replace my antiquated Rube Goldberg machine.
So now I'm learning about shooting Stop Motion and I have it together EXCEPT I see light and dark bands moving across my composition. Much reading and conversations on various Stop Motion sites and I find I need a different lens, a manual lens. Because the auto focus and auto shutter on my camera is causing the banding. BUT the only lens I can afford is a 100MM lens which only focuses at certain distances and does NOT have zoom capabilities.
Still with me?
So I have to move the "stage" in concert with the focusing of the lens to simulate zooming. Pull my old camera dolly system out, cut down the code, rebuild a moving stage which works under, you guessed it DMX control. So here I am back figuring out how to get this system to run the Arduino code when I start the stage movement hardware and I run into the SAME PROBLEM I HAD MONTHS AGO! For some reason which I couldn't figure out months ago. Delays, manual switches, yada,yada. What DOES work is if the code doesn't go into initialization correctly, by hitting the reset on the Arduino everything is happy. Since I have 4,040 single frames of Legos moving miniscule amounts and I have ANOTHER deadline, this time for a fairly large film festival I don't have the time to beat my brains out again trying to figure it out. If throwing a manual reset switch makes the system run then that's what I'll do.
But I do thank you for the suggestion and for the probable request to do a schematic of my system which I also don't have time for.

camsysca, thanks for the reset info. Never thought to look at other pins on the board. Wiring is not an issue for me, it;s the troubleshooting without proper equipment, i.e. scope. That is why I want as simple as possible. The values I'm having trouble with are values returned by the DMX board. Again the issue is that the DMX board takes over serial operation so trying to use Serial monitor is a non-starter which is why I thought if I could throw a simple hex display up I could see what values were being returned and then figure out the code issue.

AGAIN MANY THANKS to all you responding folks!

Best,

Joe B

@joebataz well, this might be a case where software serial, a quickie RS232 adapter, and a PC with terminal software would make a usable display for the purpose of seeing the two values. But we don't know much about your use case, despite what you've told us.
Or, use software serial to send the two values to another Nano/Uno, which receives using software serial and displays to Serial Monitor. That might be your quickest route to a usable display of values.

@camsysca Thank you for the ideas! I'll have to take a look when I get home and see if I can get something cobbled together. Here's all the code as it exists. LTargPos and LCurPos are the variables I need to see. This code worked in the larger program so I'm kind of puzzled why it doesn't work here. The major difference is that in addition to the "Long" code there was "Tilt" and "Pan" code which was identical except for pin assignments and min/max values.


#include <Conceptinetics.h>
//setup 3 DMX channels
#define DMX_SLAVE_CHANNELS 3 
DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );



//longitudinal stepper
#define LdirPin 8
#define LstepPin 9
#define Llimit 10
#define minLpos 100
#define maxLpos 2000

//initialize stepper variables
//longitudinal
int Ldelay = 1000;
int LTargDelay = 500;
int LTargPos = 5500;
int LCurPos = 0;
int lInit = 0;
boolean longInit = false;

//initialize DMX variables
int p1 = 0;   //long pos
int p2 = 0;   //long delay
int p3 = 0;   //extra


void setup() 
{ 
  delay(3000);

  dmx_slave.enable ();  
  dmx_slave.setStartAddress (20);

  //setup steppers
  //longitudinal
  pinMode(LdirPin, OUTPUT);     
  pinMode(LstepPin, OUTPUT);
  pinMode(Llimit, INPUT_PULLUP);
 
  //set calibrate direction  
  //logitudinal
  digitalWrite(LdirPin, LOW);
  digitalWrite(LstepPin, LOW);
 
  
 //place steppers at ~ midrange
 //initialize long stepper - set LCurPos = 5500
  InitLong(); 
}


void loop() 
{
     GetParams();// get the position values from Dragonframe

    if (LTargPos != LCurPos) {
      if ((LTargPos > minLpos) && (LTargPos < maxLpos))
      {
        int lDiff = LCurPos - LTargPos;
        if (lDiff < 0) digitalWrite(LdirPin, HIGH); else digitalWrite(LdirPin, LOW);
        while (LTargPos != LCurPos) {
          RunLong();
          lDiff = LCurPos - LTargPos;
          if (lDiff < 0) LCurPos++;else LCurPos--; 
        }
      }     
    }
}
void GetParams()
{
    p1 = dmx_slave.getChannelValue(1);//long pos      
    p2 = dmx_slave.getChannelValue(2);//long delay
    LTargPos = map(p1,0,255,minLpos,maxLpos);
} 


void RunLong()
{
  digitalWrite(LstepPin, HIGH);
  delayMicroseconds(Ldelay);
  digitalWrite(LstepPin, LOW);
  delayMicroseconds(Ldelay);
}

void InitLong()
{
  //Run long stepper left until limit switch is press - Llimit pressed = 0  
  while (digitalRead(Llimit)) {
    digitalWrite(LstepPin, HIGH);
    delayMicroseconds(Ldelay);
    digitalWrite(LstepPin, LOW);
    delayMicroseconds(Ldelay);
  }
  digitalWrite(LdirPin, HIGH);
  LCurPos = 0;
  for (int x = 0;x < 2000;x++){
    digitalWrite(LstepPin, HIGH);
    delayMicroseconds(Ldelay);
    digitalWrite(LstepPin, LOW);
    delayMicroseconds(Ldelay);
    LCurPos++;
  }
}


Best,

Joe B

I don't know anything about the dmx side of things. My concern would be whether it's so timing-sensitive that it and software serial cannot co-exist, which is very possible.

You're sort of stuck with a one-serial-port processor. I'd really lean towards throwing in an I2C-based LCD, and displaying your values there. I2C is a hardware protocol, so shouldn't interfere with serial/DMX. Of course, you'd have to have A4 and A5 uncommitted, so there's that complication.
Although they consume more resources, you could also use a small OLED, which gives you more character space. Not a need for your present usage, but you never know...

Not a complication at all. I've only used 5 - 13 for data sent to the stepper driver and for the hardware limit switches.

I just added what I think is the I2C code that I'll need. It compiled so I won't have the Serial issue. Now I just have to go back into my old code and see how I was driving the LCD display. I'll have to modify it to handle the I2C protocol. If you're interested I'll post the code and I REALLY need to draw up a schematic. I got a new version of Fritzing and of course it blew up so I'm talking with those folks about the issue I'm having. They seem pretty responsive.

Thanks again!

Best, Joe B

If you are using a 1602 or 2004 type of I2C enabled character LCD the best library to use is the hd44780 library instead of LiquidCrystal_I2C. It will automatically determine the I2C address and the LCD to I2C backpack pinmapping making using the LCD an almost plug and play deal.

1 Like

Sorry, was away. What @groundFungus said, in bold. Absolutely the best way forward for all but the most unusual LCDs.

I had to go get the library and everything still compiles. BTW I am using a 2004A Sunfounder. I will go see if I can find some example code. The stuff I wrote 7 or 8 years ago is confusing, even with all the commenting I did. I don't think I need all that code. Here is what I have so far, I'm only setting up to send out a single value but the 2004 is a 20 character by 4 line device so once I have the basics working I'll figure the rest out.
GEE, it's fun to program again! Especially with the excellent help......

Best,
Joe B

Whoops, forgot the code:


#include <Conceptinetics.h>
#include <Wire.h>
#include <hd44780.h>

byte rcvData = 255;



//setup 3 DMX channels
#define DMX_SLAVE_CHANNELS 3 
DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );



//longitudinal stepper
#define LdirPin 8
#define LstepPin 9
#define Llimit 10
#define minLpos 100
#define maxLpos 2000

//initialize stepper variables
//longitudinal
int Ldelay = 1000;
int LTargDelay = 500;
int LTargPos = 5500;
int LCurPos = 0;
int lInit = 0;
boolean longInit = false;

//initialize DMX variables
int p1 = 0;   //long pos
int p2 = 0;   //long delay
int p3 = 0;   //extra


void setup() 
{ 
  delay(3000);
  Wire.begin(0x14);
  /*Event Handlers*/
   Wire.onRequest(DataRequest);


  dmx_slave.enable ();  
  dmx_slave.setStartAddress (20);

  //setup steppers
  //longitudinal
  pinMode(LdirPin, OUTPUT);     
  pinMode(LstepPin, OUTPUT);
  pinMode(Llimit, INPUT_PULLUP);
 
  //set calibrate direction  
  //logitudinal
  digitalWrite(LdirPin, LOW);
  digitalWrite(LstepPin, LOW);
 
  
 //place steppers at ~ midrange
 //initialize long stepper - set LCurPos = 5500
  InitLong(); 
}


void loop() 
{
     GetParams();// get the position values from Dragonframe

    if (LTargPos != LCurPos) {
      if ((LTargPos > minLpos) && (LTargPos < maxLpos))
      {
        int lDiff = LCurPos - LTargPos;
        if (lDiff < 0) digitalWrite(LdirPin, HIGH); else digitalWrite(LdirPin, LOW);
        while (LTargPos != LCurPos) {
          RunLong();
          lDiff = LCurPos - LTargPos;
          if (lDiff < 0) LCurPos++;else LCurPos--; 
        }
      }     
    }
}
void GetParams()
{
    p1 = dmx_slave.getChannelValue(1);//long pos      
    p2 = dmx_slave.getChannelValue(2);//long delay
    LTargPos = map(p1,0,255,minLpos,maxLpos);
    DataRequest();
} 


void RunLong()
{
  digitalWrite(LstepPin, HIGH);
  delayMicroseconds(Ldelay);
  digitalWrite(LstepPin, LOW);
  delayMicroseconds(Ldelay);
}

void InitLong()
{
  //Run long stepper left until limit switch is press - Llimit pressed = 0  
  while (digitalRead(Llimit)) {
    digitalWrite(LstepPin, HIGH);
    delayMicroseconds(Ldelay);
    digitalWrite(LstepPin, LOW);
    delayMicroseconds(Ldelay);
  }
  digitalWrite(LdirPin, HIGH);
  LCurPos = 0;
  for (int x = 0;x < 2000;x++){
    digitalWrite(LstepPin, HIGH);
    delayMicroseconds(Ldelay);
    digitalWrite(LstepPin, LOW);
    delayMicroseconds(Ldelay);
    LCurPos++;
  }
}
void DataRequest()
{
  Wire.write(LTargPos);
}

Your code is incorrect in the usage of the hd44780 library. You are missing an include, a constructor and a begin(), at least. See the examples.

Here is the path to the examples for the 2004 display, documentation and diagnostic (in case you have trouble with the display).

Also, if you are using other I2C devices, you may have to specify the address of the LCD in its constructor. The automatic detection does not work perfectly with other parts on the bus.

@groundFungus Got a lot to read but that will only make me understand it all much better. I also assume that the include I'm missing is #include <hd44780ioClass/hd44780_I2Cexp.h>?
After I go thru this example I'll let you know if I have any questions. Cool?

Yes.

Freezin'. Ask away.

Would you like for me to add the missing hd44780 bits?

1 Like