Loading...
  Show Posts
Pages: [1]
1  Using Arduino / Project Guidance / Multiple serial channels on: May 04, 2012, 07:43:57 pm
I am using a 2560 Mega as an interface card for a machine control panel, communicating using the Modbus protocol over the USB serial channel. Since mouse and keyboard also use USB, I modified the Modbus library to allow the user to specify an alternate serial channel. After the usual compilation issues, I got a compiled version running, but was getting garbage communications. For debugging, I started adding Serial.print statements (output to the SDK monitor screen). At one call level, the print statements caused the program to start communicating properly over the other serial channel. Such behavior suggest a timing issue somewhere deep in the Arduino monitor software.
Has anyone observed similar behavior, or gotten multiple serial channels to operate successfully? Any suggestions, other than living with possible bandwidth bottlenecks?

Oh - this was compiled with the latest SDK version (Arduino 1.0)

Thanks

lloyd
2  Using Arduino / Interfacing w/ Software on the Computer / Re: modbus communication on: July 06, 2011, 03:48:32 pm
here's the master:
-----------------------------------------------------------------------------------
#include "modbus_rtu.h"
#include "../hurco.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

//   #define COMM_PORT      "/dev/ttyUSB0"
#define COMM_PORT      "/dev/ttyACM0"

#define COMM_PARITY      "even"

/* Modbus RTU common parameters, the Slave MUST use the same parameters */
enum {
        COMM_BPS = 115200,
        MB_SLAVE = 1,   /* modbus slave id */
};


int main(int argc, char *argv[])
{
    int err = 0;
    int val = 0;
    int inregs[MB_REGS];
    int fd = set_up_comms(COMM_PORT, COMM_BPS, COMM_PARITY);
    int lite = 1;
    int lite_count = 0;
    int i;
// testing, let everything settle
sleep(1);

    /* turn off leds */
    preset_single_register(MB_SLAVE,(MB_IND+1), val, fd);

    while(1){

       err = read_holding_registers( MB_SLAVE, (MB_COUNT + 1), MB_REGS, inregs, MB_REGS,fd);
for( i = 0; i < MB_REGS; i++){
   inregs ^= 0xffff;
   fprintf(stderr, "%d: %0x\n", i,  inregs[ i]);
   }
fflush(stderr);
       preset_single_register(MB_SLAVE,(MB_IND+1), lite, fd);
       lite <<= 1;
       if( ++lite_count >= LIGHT_COUNT){
          lite =1;
          lite_count = 0;
          }
       usleep( 500000);
  //     sleep(2);
       }
}
---------------------------------------------------------------------------------

and the arduino sketch:
----------------------------------------------------------------------------------
#include <ModbusSlave.h>

#include "hurco.h"
  /*
  Hurco 3
  sketch to scan a machine tool control panel, report the state,
  control associated indicator lights
 
  1st iteration 4/20/11 ldw
   4/30/11 ldw fold in the modbus comm package
   6/12/11 ldw testing indicators, integrated .h file
   6/26/11 ldw  add encoder handling
*/
// for testing lights
#define LIGHT_DLY 3    // X 50 msec -> 5 sec cycle

ModbusSlave mbs;


//global/static variables

enum PinAssignments {
  encoderPinA = 2,   // interrupt 0
  encoderPinB = 3,   // interrupt 1
//  encoderPinA = 20,   // interrupt 3
//  encoderPinB = 21,   // interrupt 2

  clearButton = 8   // not used in hurco
};

volatile unsigned int encoderPos = 0;
unsigned int lastReportedPos = 1;

boolean A_set = false;
boolean B_set = false;


unsigned int modbus_regs[MB_REGS];
unsigned int last_regs[MB_REGS];
int row = SCAN_ROWS;
int heart = 0;

// for testing lights
int light_count = LIGHT_DLY;
int light_idx;

SCAN_STRUCT   scan_set[] =
{ 22, &modbus_regs[MB_SWITCH1],0,
  23, &modbus_regs[MB_SWITCH1],1,
  24, &modbus_regs[MB_SWITCH2],0,
  25, &modbus_regs[MB_SWITCH2],1};

LIGHT_STRUCT lights[] =
{ AUTO, 53,
  MAN,  52,
  MDI,  51,
  CW,   50,
  CCW,  10,
  BRAKE, 11,
  MACH_ON, 12,
  ESTOP,  13,
  MIST,   14,
  FLOOD,  15};

// array of i/o pins used for leds
//int indicators[] = {
//  10, 11, 12, 13, 50, 51, 52, 53};

void setup(){
  int i;
//clear output registers
  for (i=0; i < MB_REGS; i++){
    modbus_regs =0;
    last_regs = 0;
    }
//setup scan pins
pinMode( 22, OUTPUT);digitalWrite(22,HIGH);
pinMode( 23, OUTPUT);digitalWrite(23,HIGH);
pinMode( 24, OUTPUT);digitalWrite(24,HIGH);
pinMode( 25, OUTPUT);digitalWrite(25,HIGH);
//setup led pins
for( i= 0; i < LIGHT_COUNT; i++){
  pinMode( lights[ i].port_pin, OUTPUT);
  digitalWrite( lights.port_pin, LOW);
}
// and turn on the relay providing power to the lights
pinMode( LIGHT_RELAY, OUTPUT);
digitalWrite( LIGHT_RELAY, LOW);

//configure column port as 8 bits in, with pullups
//corresponds to pins 37 (bit 0) to 30 (bit 7)
DDRC=0;
PORTC=B11111111;

// setup modbus communications
mbs.configure( MB_ADDR, BAUD, PARITY, TXENPIN);

// setup encoder handling
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(clearButton, INPUT);
  digitalWrite(encoderPinA, HIGH);  // turn on pullup resistor
  digitalWrite(encoderPinB, HIGH);  // turn on pullup resistor
  digitalWrite(clearButton, HIGH);

// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);

}



void loop(){
if(++row >= SCAN_ROWS){
    check_modbus();
    row = 0;
    }
scan_row( row);
delay(50);
}

void check_modbus(){
int i;
int ind_mask = 1;
//noInterrupts();
modbus_regs[MB_COUNT] = encoderPos;
encoderPos = 0;
//interrupts();

mbs.update( (int *)modbus_regs, MB_REGS);

for( i = 0; i < LIGHT_COUNT; i++){
//    if(modbus_regs[ MB_IND] & ind_mask)
        digitalWrite( lights[ i].port_pin, (modbus_regs[ MB_IND] & ind_mask));
//    else
//        digitalWrite( lights[ i].port_pin, LOW);
    ind_mask <<= 1;
    }
}


void scan_row( int row){
  unsigned int temp;
  digitalWrite( scan_set[ row].row_pin, LOW);
  delay(5);
  temp=PINC;
  if( scan_set[row].shift){
      *scan_set[row].reg &=HIGH_MASK;
      *scan_set[row].reg |= temp<<8;
  }
  else{
      *scan_set[row].reg &=LOW_MASK;
      *scan_set[row].reg |=temp;
  }
  digitalWrite( scan_set[ row].row_pin, HIGH);
}

// interrups; one for each channel
// Interrupt on A changing state
void doEncoderA(){
  // Test transition
  A_set = digitalRead(encoderPinA) == HIGH;
  // and adjust counter + if A leads B
  encoderPos += (A_set != B_set) ? +1 : -1;
}

// Interrupt on B changing state
void doEncoderB(){
  // Test transition
  B_set = digitalRead(encoderPinB) == HIGH;
  // and adjust counter + if B follows A
  encoderPos += (A_set == B_set) ? +1 : -1;
}
-----------------------------------------------------------------------------------------

both programs compile with no warnings
3  Using Arduino / Interfacing w/ Software on the Computer / modbus communication on: July 06, 2011, 10:01:10 am
I am implementing a control panel using a 2560mega board, using the modbus_slave library to manage the communication
protocol requirements. Physical communication is via USB (115K baud, even parity). For testing, the controller program reads 4 holding registers and writes 1 register in a 1/2 second loop. Approximately half the times I start the controller program, I get garbage data reported in the read registers, plus communication timeout errors on every pass through the controller loop. When the program does start properly, it will run for days without error.
Has anyone seen similar behavior and found a fix?

thanks

lloyd
4  Using Arduino / LEDs and Multiplexing / 2560 total current draw on: May 02, 2011, 06:53:43 am
I'm planning on using a 2560mega  to manage a control panel for a machine tool, which will have multiple
indicators. I want to use high-intensity LEDs, which draw 30-50 ma each. The spec sheet says 40 ma max per output pin, but I've seen nothing about total current draw allowable for the chip - essentially, how many simultaneous LEDs can I light up at one time, assuming 30 ma each?

Relatedly, I will need a small amount of 5V power for other peripherals; how much current can the 2560 on-board regulator supply?

Thanks

ldw
5  Using Arduino / Programming Questions / port-related questions on: April 14, 2011, 06:33:21 am
I'm planning to use a 2560 board to multiplex 40-50 switches in a machine control panel to an emc2 controller via modbus. Scanning this number of inputs will be much more efficient if done as parallel operations, via port manipulations, rather than as single bits. Even the 2560 doesn't provide enough uncommitted dio pins, so I will need to use some of the ports that have been assigned to other uses (analog in, for example). I haven't been able to find in the documentation, either Arduino or AVR, what process, if any, is needed to set the operating mode of a port to either general digital i/o or special purpose. Can someone clarify this?

On a somewhat related note, I have been searching for definitions of the port manipulation registers (DDR etc) for the 2560 board. A previous post on this board provided:

for your ATMega 2560 controller, you can find the information in file "C:\arduino-0022\hardware\tools\avr\avr\include\avr\iomxx0_1.h".
So there's no need to define the register names yourself.

 my installation of arduino-0022 (on ubuntu 10.04) shows nothing in the tools directory but arvdude. Anybody have an idea where the rest of the data went?

thanks in advance

ldw
Pages: [1]