Version: 1.0.0
General Setup
The following connections are required
- RJ45 network connector can go to either IN or OUT connector as the Ethernet controller is setup as a switch.
- Programming ribbon connector connects to i-Jet.
- 4 pin power connectors to 24V power supply. Power supply is wired in picture below.
- USB on the motor is not required.
- This is used to configure the network setup. This can be set in the program as shown below in the Socket Setup.
- It is also used to load a firmware image
General usage
- The MAC address on the two motors are set to to 70-B3-D5-96-E0-05 and 70-B3-D5-96-E0-06. If these are not read from the EEPROM they will need to be set in the program.
- There is a bootloader which is separate to the main code. If the code is set to execute from flashrom in IAR Embedded Workbench it will overwrite the bootloader.
- Development should be done using the RAM Debug option.
- Once development is complete it can be loaded as an image through the USB.
Socket API
Socket Setup
There are 4 sockets available in firmware. In the supplied firmware Socket1 is used for direct communication to the motor. Socket2 is used for Modbus-TCP communication. They can be reassigned as needed.
There is a 5th socket used only for setup. This socket should not be changed or used.
The IP address, socket type (UDP/TCP) and port numbers are typically set using the USB interface. The values are saved in the EEPROM and recalled on power-up. However, for development purposes, the ethernet and socket information can be set in code
File | net_func.c |
---|---|
Function | ER ReadEEP_NetData(void) |
Example | ER ReadEEP_NetData(void) - net_func.c gNET_ADR[0].ipaddr = 0xC0A80114; SOC1_PORT = 10001; SOC1Type = TYPE_TCP; SOC2_PORT = 502; SOC2Type = TYPE_TCP; SOC3_PORT = 123; SOC3Type = TYPE_TCP; SOC4_PORT = 456; SOC4Type = TYPE_TCP; //Additional device data can be set such as //gNET_ADR[0].gateway //gNET_ADR[0].mask //DHCP_ENA - 1/0 |
Socket Send
Each socket has a function that can be called to send data. Passed arguments are a byte array and length. The array is then copied to the sockets send buffer before setting a flag letting the OS know to send the data.
The default size for the socket send buffers are
UB SOC1TxBuffer[256]; UB SOC2TxBuffer[64]; UB SOC3TxBuffer[64]; UB SOC4TxBuffer[64];
The buffer sizes can be increased as needed. They are found in net_func.c
The socket send functions are
File | net_func.c |
---|---|
Function | void SendSOC1(UB *buffer, UB len) |
Example | The example below is used to send data received from the motor controller to socket1 ControlCommunication(void) - uart.c UB buffer[256]; UB len; ... SendSOC1(buffer, len); //send out on Ethernet ... |
Socket Receive
Each socket has a function that is called when data is received. This function has the length of the received data. The received data is in the sockets received buffer.
The default size for the socket receive buffers are
UB SOC1RxBuffer[256]; UB SOC2RxBuffer[64]; UB SOC3RxBuffer[64]; UB SOC4RxBuffer[64];
The buffer sizes can be increased as needed. They are found in net_func.c
The socket receive functions are
File | net_func.c |
---|---|
Function | void ReceiveSOC1(UH len) |
Example | The example below is used to receive on socket1 and send it to the motor. ReceiveSOC1(UH len) - net_func.c static void ReceiveSOC1(UH len) { putDataToMotor(SOC1RxBuffer, len); } |
Motor Data
There are two structs used used in the transmit and receive of motor data.
- Receive data from the motor - MotorInfoStruct
- Transmit data to the motor - MotorControlStruct
The structs are then passed as arguments to motor_SetControl and motor_GetInfo
Receiving Motor Info Data
The following struct is located in motorcontrol.h
typedef struct { //DO not change this order. Used in memcopy with CSI structure long CPUTime; long ActualPosition; long TargetPosition; unsigned short MotorStatus; short PercentActualCurrent; short PercentOverloadTorque; short AnalogIn; unsigned char DigitalIN; unsigned char Temperature; short DCVoltage; unsigned short usReserved; unsigned char MotionGeneratorDisplay; unsigned char ErrorCode; //not in mem structure long ActualSpeed; }MotorInfoStruct;
A local copy of the struct can be updated using the following function
File | motorcontrol.c |
---|---|
Function | ER motor_GetInfo(MotorInfoStruct *MotorInfoAddr) |
Example | The example below is used to populate a local info struct in main.c. It is called cyclically in the 125us task. Note that in the source provided it is commented out. Example - motor_GetInfo MotorControlStruct MotorControlMDB; MotorInfoStruct MotorInfoMDB; void timer125us_tsk( void ) { UB SpeedCounter=0; while(1) { P_EX_INPUT5 = ~P_IN1; P_EX_INPUT6 = ~P_IN4; P_OUT1 = ~P_EX_OUTPUT3; ScanIO(); if(SpeedCounter == 200) //update speed every 25ms. { UpdateSpeed(); SpeedCounter=0; } SpeedCounter++; //Testing functions below motor_GetInfo(&MotorInfoMDB); motor_SetControl(&MotorControlMDB); slp_tsk(); } } |
Sending Motor Control Data
The following struct is located in motorcontrol.h
typedef struct { //DO NOT change this order. Used in memcopy with CSI structure long TargetPos; long TargetSpeed; short TargetTorque; unsigned short TargetAcc; unsigned short TargetDec; unsigned char ControlWord; unsigned char MotionGenerator; unsigned char DigitalIO; }MotorControlStruct;
A local copy of the struct can be used to update the struct transmitted to the motor using the following function
File | motorcontrol.c |
---|---|
Function | ER motor_SetControl(MotorControlStruct *MotorControlAddr) |
Example | The example below is used to populate a local info struct in main.c. It is called cyclically in the 125us task. Note that in the source provided it is commented out. Example - motor_GetInfo MotorControlStruct MotorControlMDB; MotorInfoStruct MotorInfoMDB; void timer125us_tsk( void ) { UB SpeedCounter=0; while(1) { P_EX_INPUT5 = ~P_IN1; P_EX_INPUT6 = ~P_IN4; P_OUT1 = ~P_EX_OUTPUT3; ScanIO(); if(SpeedCounter == 200) //update speed every 25ms. { UpdateSpeed(); SpeedCounter=0; } SpeedCounter++; //Testing functions below motor_GetInfo(&MotorInfoMDB); motor_SetControl(&MotorControlMDB); slp_tsk(); } } |
Writing Motor Registers
There are additional registers on the motor for setting up parameters such as home routines, inputs, outputs, resolution, etc. These registers can be written to with the function motor_SetRegister. There is a queue size of 16 registers. 1 register is written each 100us.
File | motorcontrol.c |
---|---|
Function | ER motor_SetRegister(unsigned short dataAddr, long value); |
Example | The example below is used by modbus to write to a specific register Example - motor_SetRegister - modbus.c static ER_RET modbusWriteRegisters(void) { UH mdbAddr; long value; UB numRegisters; char str[32]; numRegisters = ModbusMessage.numRegisters>>1; for (int i = 0; i < numRegisters; i++) { mdbAddr = ModbusMessage.startingAddress + (i<<1); memcpy(&value, &ModbusMessage.data[i<<2],4); value = swapLongBytes(value); motor_SetRegister(modbusToMotorRegisters(mdbAddr),value); if(Get_LogData()) { sprintf(str, "MDB W:%d=%d\r\n",mdbAddr,value); putStringToLog(str); } } return ER_OK; } |
Reading Motor Registers
There are additional registers on the motor for setting up parameters such as home routines, inputs, outputs, resolution, etc. These registers can be read with the following function
File | motorcontrol.c |
---|---|
Function | ER motor_GetRegister(unsigned short dataAddr, long *value); |
Example | The example below is used by modbus to read a specific register Example - motor_GetRegister - modbus.c static long GetMdbRegisterData(UH addr) { long res = 0; addr = modbusToMotorRegisters(addr); motor_GetRegister(addr, &res); return swapLongBytes(res); //modbus uses MSB on 16bit values. } |
Testing the Motor
The motor can be controlled to target positions by setting the following in the MotorControlStruct passed.
Variable | Description | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MotionGenerator | Sets the motion control type. 0 - no motion type | |||||||||||||||||||||
Controlword | The control word is used as bits. Only B0 is used in Torque mode.
| |||||||||||||||||||||
TargetPos | Set the target position in a position control move. Example: TargetPos=1000 will set the target position to 1000 counts.
| |||||||||||||||||||||
TargetSpeed | Set the target speed in the resolution set. This is typically 1000 counts/revolution with a speed unit of 100counts/s. This will also set the maximum allowed speed in torque mode. Example TargetSpeed = 10 will set the target speed to 1000 as the default unit is 100counts/s. This will rotate the motor at 1 revolution/s. Max speed is 3000 rpm. I.e. TargetSpeed=500 is max value at default resolution (register K37)
| |||||||||||||||||||||
TargetAcc | Set the target acceleration in 1000 counts/s2. Example TargetAcc = 100 will set the target acceleration to 100000 counts/s2. | |||||||||||||||||||||
TargetDec | Set the target deceleration in 1000 counts/s2. Example TargetAcc = 20 will set the target deceleration to 20000 counts/s2. | |||||||||||||||||||||
TargetTorque | Set the target torque in 0.1% of rated torque. Example TargetTorque = 1250 will set the tarqet torque to 125% of rated which is peak torque. Range is ± 1250. Only torque mode uses a -ve torque. Setting a negative torque will run the motor CCW. |
//First set the motion generator to 3. MotionGenerator = 3 //Set all targets TargetPos = 100000 TargetSpeed = 10 TargetTorque = 1250 TargetAcc = 10 TargetDec = 10 //set the controlword= 1 to start the motion ControlWord = 1 //at any point change the speed, acceleration or position to change the profile TargetPos = -10000 //run to absolute -10000