Serial input and the interrupt timer in DMD library

The Dot Matrix Display (DMD) is a 32x16 array of high-brightness LEDs for visually striking effects. [Product Page]
Post Reply
hipsi
Posts: 10
Joined: Mon Aug 08, 2016 3:24 am

Serial input and the interrupt timer in DMD library

Post by hipsi » Thu Sep 29, 2016 4:01 am

Is it possible that the interrupt timer can cause issues with an incoming serial string on the arduino?

Here's my scenario. I have an arduino (A1) that takes a HEX string input over SoftwareSerial, pulls a couple of relevant bytes out of it, and converts them to ASCII in a character array. I want it then to dmd.drawString the array to my DMD. If I Serial.Print my array it looks perfect.
For simplicity I'm using a separate arduino (A2) for the DMD control. I have a sketch on it which is a minor modification of the example sketch, that successfully works when I feed a text string into its SoftwareSerial input. But if I link the serial TX from A1 into the RX of A2 and have a Serial.Print line to show what is read into the inChar array on (A2) it's a mess. I get maybe a couple of characters that are correct, but they're interwoven between crap.

If I load the SoftwareSerial example sketch into A2 the serial string is received correctly. I'm scratching my head over this. My sketches are really messy at the moment because while I've been trying to get it to work I keep commenting out stuff and trying new stuff. I'll tidy them up and then post them up here a bit later.

User avatar
stryker
Posts: 246
Joined: Sat Jan 14, 2012 2:44 pm

Re: Serial input and the interrupt timer in DMD library

Post by stryker » Thu Sep 29, 2016 6:19 am

What kind of Arduino are you using? Reason I ask is I have had issues with some (granted, clone) Arduinos with soft serial recently. The same code worked fine with some and not others and I think comes down to the accuracy of the microcontroller clock source.

hipsi
Posts: 10
Joined: Mon Aug 08, 2016 3:24 am

Re: Serial input and the interrupt timer in DMD library

Post by hipsi » Thu Sep 29, 2016 7:15 am

they are both Duinotech Nanos. I haven't thought to try different ones.

User avatar
stryker
Posts: 246
Joined: Sat Jan 14, 2012 2:44 pm

Re: Serial input and the interrupt timer in DMD library

Post by stryker » Thu Sep 29, 2016 9:08 am

Can you share your code? I'm not convinced re-reading your original post that we had the same issue. Thanx Geoff

hipsi
Posts: 10
Joined: Mon Aug 08, 2016 3:24 am

Re: Serial input and the interrupt timer in DMD library

Post by hipsi » Thu Sep 29, 2016 9:19 am

I left it around lunch time to move onto some other work and I decided to have another look at it before I left the office. I added a 5 ms delay after my while Serial.available line and it is now working perfectly. Now I just have to tidy the code up, and next step is to see if I can combine it all onto one arduino.
Last edited by hipsi on Sat Oct 08, 2016 8:07 pm, edited 1 time in total.

Anon_guy
Posts: 6
Joined: Sat Oct 08, 2016 4:29 pm

Re: Serial input and the interrupt timer in DMD library

Post by Anon_guy » Sat Oct 08, 2016 6:11 pm

For anyone else having this problem, this is due to Serial library and TX, RX being related together, it is mentioned in Arduino's documentation that you cannot use Serial library and rx,tx pins together or simultaneously hence when hipsi added delay it worked as it was not simultaneous anymore

prescol
Posts: 1
Joined: Tue Jul 25, 2017 9:52 am

Re: Serial input and the interrupt timer in DMD library

Post by prescol » Tue Jul 25, 2017 10:05 am

Hi, i had the same problem, but i could not change the speed of communication. I ended skipping the timer1 AttachInterrupt and making refresh with a mathematical timer with millis. Each 3 millis ScanDMD() is called.
The main problem here is that you cant make use of delay() anymore, because you need your program running smooth without stop. So i ended making my own delay function based on micros.

Here i post so anyone could use it.

Code: Select all


//   Custom delay based on micros
// USE:
// if(customDelay(step id,time in milliseconds)){ logic }

unsigned long lastTime = 0;
unsigned int currentStep = 1;
unsigned int maxStep = 2; // Max number of steps
boolean processed = false;

boolean customDelay(unsigned int stepId = 0, unsigned long duration  = 0 ) {

  unsigned long currentMicros = micros();
  unsigned long durationMicros = duration * 1000;

  if (stepId == currentStep)
  {
    //Active element

    if ((unsigned long)(currentMicros - lastTime) >= durationMicros)
    {
      lastTime = currentMicros;
      if (currentStep == maxStep)
      {
        currentStep = 1;
      } else
      {
        currentStep++;
      }
      processed = false;

      return false;
    }

    if (processed)
    {
      return false;
    }
    processed = true;
    return true;
  }

  return false;

}
Then, in your loop code must wrap those functions that need a delay AFTER.

Code: Select all

if(customDelay(1,5000)){ logic}

if(customDelay(2,3000)){ more logic}

if(customDelay(3,2000)){ and more logic}
The first argument is an identifier of the order of each blocks. It is recommended to follow a natural order. You cannot skip any number or the program will stop working.

It´s also important to define the last number you used in var maxStep, so customDelay could now when the cycle has ended.

Using this can use Serial input as fast as ever and forgot problems with data loss

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests