process_encoder.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2016-17, Universidad de Almeria
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage, Inc. nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 
36 /*Beginning of Auto generated code by Atmel studio */
37 #include <Arduino.h>
38 /*End of auto generated code by Atmel studio */
39 
40 #include "arduinodaq2pc-structs.h"
41 #include "config.h"
42 
43 #include <Wire.h>
44 //#include <SPI.h>
45 
46 unsigned long PC_last_millis = 0;
47 uint16_t PC_sampling_period_ms = 500;
48 bool ENCODERS_active = false;
49 
51 {
52  // Config:
53  volatile int8_t encA_pin=0; // =0 means disabled.
54  volatile int8_t encB_valid=0,encB_bit=0, encB_port=0;
55  volatile int8_t encZ_valid=0,encZ_bit=0, encZ_port=0; // encZ_port=0 means no Z
56  volatile bool led = false;
57 
58  // Current encoder tick counter value:
59  volatile int32_t COUNTER = 0;
60  // Init:
62  { }
63 };
64 
66 
67 // Forward:
68 // ------ ------
69 // A: | | | |
70 // ____| |______| |_____
71 // ------ ------
72 // B: | | | |
73 // _______| |______| |_____
74 //
75 //
76 template <uint8_t index> // Generic template to generate N functions for different index of encoder=0,1,...
77 static void onEncoder_Raising_A()
78 {
79 #ifdef USE_ENCODER_DEBUG_LED
80  ENC_STATUS[index].led = !ENC_STATUS[index].led;
81 #endif
82 
83  // Avoid: digitalRead() "slow" call
84  if (ENC_STATUS[index].encB_valid)
85  {
86  const bool B = (*portInputRegister(ENC_STATUS[index].encB_port) & ENC_STATUS[index].encB_bit);
87  if (B)
88  ENC_STATUS[index].COUNTER--;
89  else ENC_STATUS[index].COUNTER++;
90  }
91  else
92  {
93  ENC_STATUS[index].COUNTER++;
94  }
95 
96 #if 0
97  if (ENC_STATUS[index].encZ_valid)
98  {
99  const bool Z = (*portInputRegister(ENC_STATUS[index].encZ_port) & ENC_STATUS[index].encZ_bit);
100  if (Z) {
101  ENC_STATUS[index].COUNTER=0;
102  }
103  }
104 #endif
105 }
106 
107 // List of function pointers, required by Arduino attachInterrupt() and also
108 // to be able to dynamically get a pointer by index, which is not directly allowed
109 // with template arguments.
110 typedef void (*func_ptr)(void);
112 {
113  &onEncoder_Raising_A<0>,
114  &onEncoder_Raising_A<1>
115  //... Add more if needed in the future
116 };
117 
119 {
121 
122  // For each software-based encoder:
124  {
125  ENC_STATUS[i] = EncoderStatus();
126 
127  ENC_STATUS[i].encA_pin = cmd.encA_pin[i];
128 
129  // Is it enabled by the user?
130  if (cmd.encA_pin[i]>0)
131  {
132  if (cmd.encB_pin[i]>0)
133  {
134  // Cache these calls to avoid repeating them in readDigital() inside the interrupt vector ;-)
135  ENC_STATUS[i].encB_bit = digitalPinToBitMask( cmd.encB_pin[i] );
136  ENC_STATUS[i].encB_port = digitalPinToPort(cmd.encB_pin[i]);
137  ENC_STATUS[i].encB_valid = true;
138  }
139  else
140  ENC_STATUS[i].encB_valid = false;
141 
142  if (cmd.encZ_pin>0)
143  {
144  ENC_STATUS[i].encZ_bit = digitalPinToBitMask(cmd.encZ_pin[i]);
145  ENC_STATUS[i].encZ_port = digitalPinToPort(cmd.encZ_pin[i]);
146  ENC_STATUS[i].encZ_valid = true;
147  }
148  else
149  {
150  ENC_STATUS[i].encZ_valid = false;
151  ENC_STATUS[i].encZ_bit = ENC_STATUS[i].encZ_port = 0;
152  }
153 
155  }
156  }
157 }
158 
160 {
161  if (!ENCODERS_active)
162  return;
163 
164 #ifdef USE_ENCODER_DEBUG_LED
166  digitalWrite(PIN_ENCODER_DEBUG_LED,ENC_STATUS[0].led);
167 #endif
168 
169  const unsigned long tnow = millis();
171  return;
172 
173  PC_last_millis = tnow;
174 
176 
177  // Atomic read: used to avoid race condition while reading if an interrupt modified the mid-read data.
178  noInterrupts();
180  {
181  tx.payload.encoders[i] = ENC_STATUS[i].COUNTER;
182  }
183  interrupts();
184 
185  // send answer back:
186  tx.payload.timestamp_ms = millis();
189 
190  Serial.write((uint8_t*)&tx,sizeof(tx));
191 }
volatile int8_t encB_port
void calc_and_update_checksum()
volatile int8_t encZ_valid
void pinMode(uint8_t, uint8_t)
#define noInterrupts()
Definition: Arduino.h:102
GLvoid *typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
void(* func_ptr)(void)
const int PIN_ENCODER_DEBUG_LED
Definition: config.h:44
volatile int8_t encB_bit
volatile int8_t encB_valid
uint16_t PC_sampling_period_ms
volatile int8_t encZ_port
EncoderStatus ENC_STATUS[TFrameCMD_ENCODERS_start_payload_t::NUM_ENCODERS]
#define OUTPUT
Definition: Arduino.h:44
void attachInterrupt(uint8_t, void(*)(void), int mode)
Definition: WInterrupts.c:70
void init_encoders(const TFrameCMD_ENCODERS_start_payload_t &cmd)
volatile int32_t COUNTER
unsigned long millis(void)
Definition: wiring.c:65
#define digitalPinToBitMask(P)
Definition: Arduino.h:178
GLuint index
volatile int8_t encZ_bit
void digitalWrite(uint8_t, uint8_t)
static void onEncoder_Raising_A()
#define RISING
Definition: Arduino.h:62
volatile int8_t encA_pin
#define interrupts()
Definition: Arduino.h:101
bool ENCODERS_active
#define portInputRegister(P)
Definition: Arduino.h:182
void processEncoders()
unsigned long PC_last_millis
#define digitalPinToInterrupt(p)
func_ptr my_encoder_ISRs[TFrameCMD_ENCODERS_start_payload_t::NUM_ENCODERS]
#define digitalPinToPort(P)
Definition: Arduino.h:177
signed int int32_t
volatile bool led


arduino_daq
Author(s):
autogenerated on Mon Jun 10 2019 12:46:03