-1
\$\begingroup\$

How can I send the string "test" from a master pic to a slave?

I'm using MicroC RS-485 library example:

http://www.mikroe.com/download/eng/documents/compilers/mikroc/pro/pic/help/rs-485_library.htm

Im trying to send string from master to slave: and seting dat[7] = "my string"; expecting dat[7] on slave with my string but im geting empty value...

Original code in the link bottom.

Master

char dat[10];                          // buffer for receving/sending messages
char i,j;

sbit  rs485_rxtx_pin  at RC2_bit;               // set transcieve pin
sbit  rs485_rxtx_pin_direction at TRISC2_bit;   // set transcieve pin direction

// Interrupt routine
void interrupt() {
  RS485Master_Receive(dat);
}

void main(){
  long cnt = 0;

  ANSEL  = 0;                          // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;                        // Disable comparators
  C2ON_bit = 0;

  PORTB  = 0;
  PORTD  = 0;
  TRISB  = 0;
  TRISD  = 0;


  UART1_Init(9600);                    // initialize UART1 module
  Delay_ms(100);

  RS485Master_Init();                  // initialize MCU as Master
  dat[0] = 0xAA;
  dat[1] = 0xF0;
  dat[2] = 0x0F;
  dat[4] = 0;                          // ensure that message received flag is 0
  dat[5] = 0;                          // ensure that error flag is 0
  dat[6] = 0;
  dat[7] = "MY STRING";

  RS485Master_Send(dat,1,160);


  RCIE_bit = 1;                        // enable interrupt on UART1 receive
  TXIE_bit = 0;                        // disable interrupt on UART1 transmit
  PEIE_bit = 1;                        // enable peripheral interrupts
  GIE_bit = 1;                         // enable all interrupts

  while (1){
                                       // upon completed valid message receiving
                                       //   data[4] is set to 255
    cnt++;
    if (dat[5])  {                     // if an error detected, signal it
      PORTD = 0xAA;                    //   by setting portd to 0xAA
    }
    if (dat[4]) {                      // if message received successfully
      cnt = 0;
      dat[4] = 0;                      // clear message received flag
      j = dat[3];
      for (i = 1; i <= dat[3]; i++) {  // show data on PORTB
        PORTB = dat[i-1];
      }                                // increment received dat[0]
      dat[0] = dat[0]+1;               // send back to master
      Delay_ms(1);
      RS485Master_Send(dat,1,160);

    }
   if (cnt > 100000) {
      PORTD ++;
      cnt = 0;
      RS485Master_Send(dat,1,160);
      if (PORTD > 10)                  // if sending failed 10 times
        RS485Master_Send(dat,1,50);    //   send message on broadcast address
     }
  }

}

Slave:

char dat[9];             // buffer for receving/sending messages
char i,j;

sbit  rs485_rxtx_pin at RC2_bit;             // set transcieve pin
sbit  rs485_rxtx_pin_direction at TRISC2_bit;   // set transcieve pin direction

// Interrupt routine
void interrupt() {
 RS485Slave_Receive(dat);
}

void main() {
  ANSEL  = 0;                        // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;                      // Disable comparators
  C2ON_bit = 0;

  PORTB = 0;
  PORTD = 0;
  TRISB = 0;
  TRISD = 0;
  PORTA = 0;
  TRISA = 0;


  UART1_Init(9600);                  // initialize UART1 module
  Delay_ms(100);
  RS485Slave_Init(160);              // Intialize MCU as slave, address 160

  dat[4] = 0;                        // ensure that message received flag is 0
  dat[5] = 0;                        // ensure that message received flag is 0
  dat[6] = 0;                        // ensure that error flag is 0

  RCIE_bit = 1;                      // enable interrupt on UART1 receive
  TXIE_bit = 0;                      // disable interrupt on UART1 transmit
  PEIE_bit = 1;                      // enable peripheral interrupts
  GIE_bit = 1;                       // enable all interrupts

  while (1) {
    if(dat[7]=="MY STRING"){
      RCA0_bit = 1;
    }

    if (dat[5])  {                   // if an error detected, signal it by
      PORTD = 0xAA;                  //   setting portd to 0xAA
      dat[5] = 0;
    }
    if (dat[4]) {                    // upon completed valid message receive
      dat[4] = 0;                    //   data[4] is set to 0xFF
      j = dat[3];
      for (i = 1; i <= dat[3];i++){
        PORTB = dat[i-1];
      }
      dat[0] = dat[0]+1;             // increment received dat[0]
      Delay_ms(1);
      RS485Slave_Send(dat,1);        //   and send it back to master
    }
  }
}

enter image description here

\$\endgroup\$
  • 2
    \$\begingroup\$ Try to narrow it down. Does the master-slave communication work, except for the LCD? The "dat[7]" in the function call looks strange. Shouldn't it be a reference to the array? You didn't include any details about the LCD_out function. \$\endgroup\$ – Dejvid_no1 Apr 16 '14 at 13:33
  • \$\begingroup\$ Well communication for me works as I used example of master and slave code witch is in the link, also added LCD 16x2 for debugging my Master and Slave communication, LCD also works great, but main problem is that I want to send String var from Master to Slave and by that I'm using char dat[10]; array, but by setting in Master array element dat[7] = "MY STRING"; I do not get any result printed on Slave LCD monitor. As both LCD Works without bugs by printing strings on it. Just not strings witch I received from master. \$\endgroup\$ – Vadimas Sizikovas Apr 16 '14 at 13:50
  • 2
    \$\begingroup\$ Your use of dat[7] is strange indeed. You are aware that dat[7] is a char and NOT a string? \$\endgroup\$ – Tut Apr 16 '14 at 14:53
  • \$\begingroup\$ Also, I have not used MicroC, but are you sure you do not need to use something like strcpy() to copy a string? \$\endgroup\$ – Tut Apr 16 '14 at 15:00
  • 1
    \$\begingroup\$ In addition, it seems that (according to the library documentation), RS485Master_Send() can only send a maximum of 3 data bytes. The string will need to be split up. The prototype is: void RS485Master_Send(char *data_buffer, char datalen, char Slave_address); where datalen is "number of bytes for transmition (sic). Valid values: 0...3." \$\endgroup\$ – Tut Apr 16 '14 at 17:12
1
\$\begingroup\$

I think you have misunderstood how C handles strings - in short, it doesn't handle strings.

dat[10] is a 10-character array, so "dat" is effectively a char pointer to dat[0], and dat[7] is a single character, the 8th item in the array. You cannot put a string of characters into it, and even if you could you are writing beyond the end (dat[9]) of the array.

A change you might try would be:

char dat[30]; // Dat is 30 chars long
dat[0] = 0xAA;
dat[1] = 0xF0;
dat[2] = 0x0F;
dat[4] = 0;      // ensure that message received flag is 0
dat[5] = 0;      // ensure that error flag is 0
dat[6] = 0;
dat[7] = 'M';
dat[8] = 'Y';
dat[9] = ' '; // SPACE in this entry, not nothing
dat[10] = 'S';
dat[11] = 'T';
dat[12] = 'R';
dat[13] = 'I';
dat[14] = 'N';
dat[15] = 'G';
dat[16] = '\0'; // C strings expect a NULL on the end

Writing off the end of the array (beyond dat[9] in your code) will be writing data into other memory, probably across other variables you're using, and is likely to case a crash.

\$\endgroup\$
  • 1
    \$\begingroup\$ Use dat[16] = '\0';, it is the convention for null termination. It tells the reader "I explicitly want a null termination of my string", rather than "I will set this byte to zero". Also, don't confuse null termination with the NULL macro, they mean entirely different things. \$\endgroup\$ – Lundin Apr 17 '14 at 11:45
  • \$\begingroup\$ @Lundin - I've edited the answer to reflect that detail. \$\endgroup\$ – John U Jul 14 '14 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.