So a bit more news. Good news! The attached screen shot from the RM CAN monitor shows 3 messages. The first message with ID 0x298 is a PDO message which is the status from the device. Second byte lower 4 bits represents what it says the outputs are set to. The top 4 bits are what it was commanded to do with those outputs.
The next message is the NMT heartbeat from node 0x718 which is my device. The 0x05 says its alive and NMT_OPERATIONAL which means it's allowed to send PDO messages with device information. Finally we have the PDO message 0x318 which is 'from' the Pi4 LinuxCNC interfaced to the Lawicel CANUSB as /dev/ttyUSB0 using the Python pySerial library. Notice the 0x04 data byte. That's the bit which is connected to the Mist ON/OFF button and that bit switches on a relay in my little device. Also attached is the python file. I put the HAL stuff in the custom.hal file. I click on the checkbox on the Axis interface and the mist relay clicks on. Click again to remove the checkmark and the mist relay goes off. And the PDO message on the monitor goes from 00 to 04 to 00. This example is the sending from AXIS via pySerial onto the CAN bus. Next step will be to present a switch press that is read by my device and shows up in the first byte of the 0x298 PDO. And I guess I'll add a heartbeat from LinuxCNC.. Lots more to do but at this point I can control relays via CAN bus. John Dammeyer > -----Original Message----- > From: John Dammeyer [mailto:jo...@autoartisans.com] > Sent: September-10-21 10:11 AM > To: 'Enhanced Machine Controller (EMC)' > Subject: Re: [Emc-users] Serial Port access > > Hi Andy, > > The output below shows CANopen PDO message #2 (0x300) to ID 0x18, 1 byte, > alternating between 0x01 and 0x00 being issued once > per second. > > pi@raspberrypi:~/projects/python $ python TestSerial.py > Sent CAN message with relay value = t318101 > Sent CAN message with relay value = t318100 > Sent CAN message with relay value = t318101 > Sent CAN message with relay value = t318100 > Sent CAN message with relay value = t318101 > > The little module shown in that photo I posted last time is connected to a > pneumatic valve on Output #1. It clicks ON and OFF once > per second. The code is running as a Python Command line program on a > standard Raspian distro. I'll bring out the Pi4 with > LinuxCNC and take a look at linking into the HAL file. > > IMHO the Python serial is very clumsy for dealing with serial with all the > format and .encode parameters for simple character strings. > The source code is attached. > > John Dammeyer > > > From: andy pugh [mailto:bodge...@gmail.com] > > On Thu, 9 Sept 2021 at 05:31, John Dammeyer < > > <mailto:jo...@autoartisans.com> jo...@autoartisans.com> wrote: > > > I've been reading > > > <http://linuxcnc.org/docs/2.4/html/hal_comp.html> > > > http://linuxcnc.org/docs/2.4/html/hal_comp.html > > > > For this application I think that a Python userspace component using > > Pyserial is probably the easier approach. > > > > <http://linuxcnc.org/docs/2.8/html/hal/halmodule.html> > > http://linuxcnc.org/docs/2.8/html/hal/halmodule.html > > > > -- > > atp
#!/usr/bin/python # Project LinuxCNC Python CANUSB Serial Port control derived from: # https://forum.linuxcnc.org/10-advanced-configuration/538-controlling-coolant-w-serial-port?start=0 # User: mozmck (Moses McKnight) # This application has been modified to use the Lawicel CANUSB treated as a USB serial port # sending out CAN messages in the CANopen format. # Version 0.1 10SEP21 # Written by # John Dammeyer # jo...@autoartisans.com import hal import time, serial # *** Issue this command from the terminal #sudo apt-get install python-serial # The serial-relays.py needs to be in the config directory for your mill. # For example: '/home/jerrybaca/emc2/configs/harborfrieghtmill' # Don't forget to sudo chmod +x serial-relays.py # *** Next Place the following lines into one of the Post HAL files. # custom.hal is probably a good enough place. #loadusr -Wn serial-relays ./serial-relays.py #net coolant-mist <= iocontrol.0.coolant-mist #net coolant-flood <= iocontrol.0.coolant-flood #net coolant-mist => serial-relays.relay1C #net coolant-flood => serial-relays.relay1D # *** End of HAL file instructions. # --- Global Variables --- h = hal.component("serial-relays") h.newpin("relay1A", hal.HAL_BIT, hal.HAL_IN) h.newpin("relay1B", hal.HAL_BIT, hal.HAL_IN) h.newpin("relay1C", hal.HAL_BIT, hal.HAL_IN) h.newpin("relay1D", hal.HAL_BIT, hal.HAL_IN) h.newpin("relay1E", hal.HAL_BIT, hal.HAL_IN) h.newpin("relay1F", hal.HAL_BIT, hal.HAL_IN) h.newpin("relay1G", hal.HAL_BIT, hal.HAL_IN) h.newpin("relay1H", hal.HAL_BIT, hal.HAL_IN) h.ready() # Serial stuff, change the serial port address by changing /dev/ttyS0 or COMx (for Windows) # For USB based Serial dongles that use FTDI hardware /dev/ttyUSB0 is often the default. # USB can be set for 115200 baud as long as the target hardware can support that since # it doesn't really delay the LinuxCNC side. ser = serial.Serial('/dev/ttyUSB0', 115200, bytesize=8, parity='N', stopbits=1, timeout=0, xonxoff=0, rtscts=0) # Create some Global variables for readability PDO = 0x300 # Process Data Object #2 NodeID = 0x18 # Device Node ID (0x01..0x7F) PDO_ID = '' # The character string that holds the OR operation of the PDO+ID RelayImage = 0 # No relays set yet. CANopenPDO_2_Msg = '' # For reporting what we send and so we don't have to recreate it each time. TempStr = "" # global so we can print what was sent. # Individual Relay State values rA = 0 rB = 0 rC = 0 rD = 0 rE = 0 rF = 0 rG = 0 rH = 0 # --- Methods --- # Function to send data to CANUSB dongle. # Parameters: # r is relayimage placed into first byte of PDO message. # Outputs: # Sends CANopenn PDO_2 message to CANUSB. # Future Enhancements: # Pass PDO #, Node ID #, Array of bytes, Number of valid bytes. def Send_PDO_2(r): global CANopenPDO_2_Msg # the message without the data. global TempStr # Now empty the Rx Buffer for sample program we don't look at received messages. while ser.inWaiting(): ser.reset_input_buffer() #discard input for now. ser.write(CANopenPDO_2_Msg.encode('utf-8')) # send PDO 3xx to node 0x18 with 1 byte # Format bit image to two hex characters TempStr = "{0:0{1}X}".format(r,2) ser.write(TempStr.encode('utf-8')) ser.write('\r'.encode('utf-8')) # Tell CANUSB to send message with <CR> character. # Function to update local PDO RelayImage # Parameters: # r is which relay to switch (1..8) # does not validate relay # to see if in range. # level is TRUE or FALSE for relay ON or OFF. # Modifies: # Global RelayImage bitmap of relay values # def Update_Relays(r, level): global RelayImage # if this isn't here then the OR operation fails with unitialized variable. # Create the text value of the relay image. bitmask = 1 << (r-1) # Select which relay to switch ON. if level == True: RelayImage = (RelayImage | bitmask) else: RelayImage = (RelayImage & ~bitmask) # --- Mainline loop --- try: # Create text value of CAN Standard ID => PDO + Node ID and Message Length of 1 PDO_ID = "{0:0{1}X}".format(PDO+NodeID,3) CANopenPDO_2_Msg = 't' + PDO_ID + '1' # Initialize CANUSB dongle ser.write('C\r'.encode('utf-8')) # Close first ser.write('F\r'.encode('utf-8')) # Clear Error Flags by reading them ser.write('S5\r'.encode('utf-8')) # set 250kbps ser.write('O\r'.encode('utf-8')) # Open CANUSB for communication. Send_PDO_2(RelayImage) # Update PDO with default value. # Main Loop while 1: relayChanged = False # If a relay has changed then this flags it. if (rA != h.relay1A): # Test the HAL pin rA = h.relay1A # if it's changed then update our image. Update_Relays(1, rA) # Update the Byte Image too relayChanged = True # And flag it so a CANopen PDO will be sent. if (rB != h.relay1B): rB = h.relay1B Update_Relays(2, rB) relayChanged = True if (rC != h.relay1C): rC = h.relay1C Update_Relays(3, rC) relayChanged = True if (rD != h.relay1D): rD = h.relay1D Update_Relays(4, rD) relayChanged = True if (relayChanged): # Did a relay change? Send_PDO_2(RelayImage) # Update PDO. except KeyboardInterrupt: raise SystemExit
_______________________________________________ Emc-users mailing list Emc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/emc-users