Hello everyone,
I am using Arduino Due to read an encoder and send it through udp using ethernet shield.
I can read the encoder value on the serial monitor by the code below:
#include <Ethernet.h>
#include <EthernetUdp.h>
volatile int64_t AbsPos , AbsPosBase;
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 20);
IPAddress remoteIP(192,168,1,10);
unsigned int localPort = 8888; // local port to listen on
unsigned int remotePort = 8888;
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
EthernetUDP Udp;
void setup() {
//Ethernet SETUP ------------------------------------------------------------------------------------------------------------------------------
Ethernet.begin(mac, ip);
Serial.begin(250000);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// start UDP
Udp.begin(localPort);
//QUAD Encoder SETUP ----------------------------------------------------------------------------------------------------------------------------
PMC->PMC_PCER1 = PMC_PCER1_PID33 // TC6 power ON ; Timer counter 2 channel 0 is TC6
| PMC_PCER1_PID34; // TC7 power ON ; Timer counter 2 channel 1 is TC7
// TC6 in capture mode
TC2->TC_CHANNEL[0].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 // capture mode, MCK/2, clk on rising edge
| TC_CMR_ABETRG // TIOA6 is used as an external trigger.
| TC_CMR_LDRA_EDGE // RA loading on each edge of TIOA6
| TC_CMR_ETRGEDG_RISING; // External TC trigger by edge selection of TIOA
TC2->TC_BMR = TC_BMR_QDEN // Enable QDEC (filter, edge detection and quadrature decoding)
| TC_BMR_POSEN // Enable the position measure on channel 0
| TC_BMR_EDGPHA // Edges are detected on both PHA and PHB
// | TC_BMR_SWAP // Swap PHA and PHB if necessary
| TC_BMR_MAXFILT(1); // Pulses with a period shorter than MAXFILT+1 peripheral clock cycles are discarded
TC2->TC_CHANNEL[0].TC_IER = TC_IER_COVFS // Interruption enable on TC_CV overflow ( TC_CV = 0xFFFFFFFF)
| TC_IER_CPCS; // Interruption enable on TC_CV underflow ( TC_CV = 0)
// Enable Compare Fault Channel 0
TC2->TC_FMR = TC_FMR_ENCF0; // To trigger an interrupt whenever TC_CV = TC_RC = 0
NVIC_EnableIRQ(TC6_IRQn);
TC2->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
TC2->TC_CHANNEL[1].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
//-----------------------------------------------------------------------------------------------------------------------------------------------
}
void loop() {
//READ ENCODERS------------------------------------------------------------------------------------------------------
//Read output spin quad encoder
AbsPos = AbsPosBase + (uint32_t)TC2->TC_CHANNEL[0].TC_CV;
printf("\nthe number: %lld\n", AbsPos);
// Problem occurs when I uncomment here
// Udp.beginPacket(remoteIP, remotePort);
// Udp.write('a');
// Udp.endPacket();
delay(10);
}
void TC6_Handler() {
uint32_t status = TC2->TC_CHANNEL[0].TC_SR;
if (status & TC_SR_COVFS) {
// TC_CV overflow --> TC_CV = 0xFFFFFFFF
AbsPosBase += 0xFFFFFFFFllu;
}
else { // if (status & TC_SR_CPCS)
// TC_CV underflow --> TC_CV = 0
AbsPosBase -= 0xFFFFFFFFllu;
}
}
The Problem occurs when I uncomment these lines:
// Udp.beginPacket(remoteIP, remotePort);
// Udp.write('a');
// Udp.endPacket();
I can still see the encoder value on serial monitor for once when I rotate the encoder, but it resets immediately for some reason. I think timer counters are reset somehow.
I have also tried to connect ethernet shield with minimum pins ICSP and pin 10 without mounting on top of arduino. Nothing changed. My encoder A and B signals are connected to pin 4 and pin5.
What can be the problem and how can I solve it?
Thank you