简体   繁体   中英

RPI with multiple pics over rs485 - CCS compiler

I am Trying to delpoy rpi3 as a master, pic as slave, and rs485 as a network medium. The rpi loops over slaves' ids, it sends them one by one, and waits for a reply from the specified slave (pic). Every pic reads the received data (address) and compares it to it's address, if it is the one, the pic must reply to the rpi.

On rpi I am using pi4j java library, while on the pics I am coding with CCS compiler.

The first problem is that when I send from the rpi an address that doesn't exist in the pics, no one replies to the rpi, and the pic I send it's address in the following instruction will also not reply.

The code for RPI is:

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.serial.*;
import com.pi4j.util.Console;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.sql.Time;


public class SerialExample {

    public void tryIt() throws InterruptedException, IOException {

        final Console console = new Console();

        // print program title/header
        console.title("<-- The Pi4J Project -->", "Serial Communication Example");

        // allow for user to exit program using CTRL-C
        console.promptForExit();

        // create an instance of the serial communications class
        final Serial serial = SerialFactory.createInstance();

        try {
            // create serial config object
            SerialConfig config = new SerialConfig();

            config.device("/dev/ttyAMA0")
                    .baud(Baud._9600)
                    .dataBits(DataBits._8)
                    .parity(Parity.NONE)
                    .stopBits(StopBits._1)
                    .flowControl(FlowControl.NONE);


            // open the default serial device/port with the configuration settings
            serial.open(config);
            final GpioController gpio = GpioFactory.getInstance();

            // provision gpio pin #01 as an output pin and turn on
            final GpioPinDigitalOutput cts = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04, "CTS", PinState.HIGH);

            while (true) {
                short i = 1; // pic ids
                while (i < 5) {
                    cts.high();
                    serial.write(String.valueOf(i));
                     System.out.println("to slave: " + i);
                    Thread.sleep(15);
                    cts.low();
                    Thread.sleep(150);
                    byte[] data = null;

                    while (serial.available() > 0) {
                        data = serial.read();
                    }
                    if (data == null) {
                        System.out.println("[null data]");
                    } else {
                        String myData = new String(data);
                        System.out.println("reply from slave: " + myData);
                    }
                    i++;
                    Thread.sleep(1000);
                }
            }
        } catch (IOException ex) {
            console.println(" ==>> SERIAL SETUP FAILED : " + ex.getMessage());
            return;
        }
    }
}

The code of the pic is common among all pics, the only difference is the ids. Pic code is

#include <12F1822.h>
#include <String.h>
#fuses NOMCLR INTRC_IO PLL_SW
#use delay(clock=32000000)

#use rs232(baud=9600, xmit=Pin_A0, rcv=Pin_A1,enable=Pin_A2, bits=8, errors, stream=RS485)

void clear_usart_receiver(void) {
    char c;
    c = getc();
    c = getc();
}
int id [] = {0, 2};

void main() {

    while (1) {
        byte message[10];
        fgets(message, RS485);
        delay_ms(10);
        if (message[0] == '2')

        {
            fputs("s2 reply", RS485);
        }
        delay_ms(10);
        clear_usart_receiver();
    }
}

I have tried removing the clear_usart_receiver(); from my pic code, then when a pic replies, the following one will not, the next one prints as planned, the following will print nothing also and so on.

One obvious problem is that sending 10 bytes of data over UART with 9600 takes longer than 10ms. You shouldn't use some home-brewed dead-wait delay, but instead poll the UART rx flag in a loop.

1 byte data = 1 start bit, 8 data bits, 1 stop bit (no partity, 1 stop bit) = 10 bits

It takes 9600^-1 us to send one bit.

9600^-1 * 10bits * 10 bytes = 10.42ms best case scenario

On the PIC side, fgets() waits for a CR character, but you don't send it from RPI. Another problem is probably

while (serial.available() > 0) { data = serial.read(); }

It seems to me that you keep on overwriting the variable data .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM