Advertisement
pardal_eletrico

Decoder de PWM

Jul 30th, 2017
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.79 KB | None | 0 0
  1. #include <PinChangeInt.h>
  2.  
  3. #include <Servo.h>
  4.  
  5. // Assign your channel in pins
  6. #define THROTTLE_IN_PIN 8
  7. #define STEERING_IN_PIN 9
  8. #define AUX_IN_PIN 10
  9.  
  10. // Assign your channel out pins
  11. #define THROTTLE_OUT_PIN 5
  12. #define STEERING_OUT_PIN 6
  13. #define AUX_OUT_PIN 7
  14.  
  15. // Os objetos Servo geram os sinais esperados pelos Controladores e Servos de Velocidade Eletrônicos
  16. // Usaremos os objetos para produzir os sinais que lemos
  17. // este código de exemplo fornece uma passagem direta do sinal sem processamento personalizado
  18. Servo servoThrottle;
  19. Servo servoSteering;
  20. Servo servoAux;
  21.  
  22. // Esses sinalizadores de bits são definidos em bUpdateFlagsShared para indicar qual
  23. // canais têm novos sinais
  24. #define THROTTLE_FLAG 1
  25. #define STEERING_FLAG 2
  26. #define AUX_FLAG 4
  27.  
  28. // contém as bandeiras de atualização definidas acima
  29. volatile uint8_t bUpdateFlagsShared;
  30.  
  31. // variáveis compartilhadas são atualizadas pelo ISR e lidas por loop.
  32. // Em loop, imediatamente pegamos cópias locais para que o ISR possa manter a propriedade do
  33. // compartilhados. Para acessar estes no loop
  34. // primeiro desligamos as interrupções com não Interrupções
  35. // tiramos uma cópia para usar no loop e as interrupções de volta de volta
  36. // o mais rápido possível, isso garante que sempre possamos receber novos sinais
  37. volatile uint16_t unThrottleInShared;
  38. volatile uint16_t unSteeringInShared;
  39. volatile uint16_t unAuxInShared;
  40.  
  41. // Estes são usados para registrar a margem ascendente de um pulso nas funções calcInput
  42. // Eles não precisam ser voláteis, pois são usados apenas no ISR. Se quiséssemos
  43. // para se referir a estes em loop e ao ISR, eles deveriam ser declarados voláteis
  44. uint32_t ulThrottleStart;
  45. uint32_t ulSteeringStart;
  46. uint32_t ulAuxStart;
  47.  
  48. void setup()
  49. {
  50. Serial.begin(9600);
  51.  
  52. Serial.println("multiChannels");
  53.  
  54.  
  55. servoThrottle.attach(THROTTLE_OUT_PIN);
  56. servoSteering.attach(STEERING_OUT_PIN);
  57. servoAux.attach(AUX_OUT_PIN);
  58.  
  59. // using the PinChangeInt library, attach the interrupts
  60. // used to read the channels
  61. PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE);
  62. PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE);
  63. PCintPort::attachInterrupt(AUX_IN_PIN, calcAux,CHANGE);
  64. }
  65.  
  66. void loop()
  67. {
  68. // criar variáveis locais para armazenar cópias locais das entradas de canal
  69. // Estes são declarados estáticos para que seus valores sejam mantidos
  70. // between calls to loop.
  71. static uint16_t unThrottleIn;
  72. static uint16_t unSteeringIn;
  73. static uint16_t unAuxIn;
  74. // local copy of update flags
  75. static uint8_t bUpdateFlags;
  76.  
  77. // check shared update flags to see if any channels have a new signal
  78. if(bUpdateFlagsShared)
  79. {
  80. noInterrupts(); // Desliga-se rapidamente enquanto tomamos cópias locais das variáveis compartilhadas
  81.  
  82. // Pegue uma cópia local de quais canais foram atualizados caso precisamos usar isso no resto do loop
  83. bUpdateFlags = bUpdateFlagsShared;
  84.  
  85. // No código atual, os valores compartilhados são sempre preenchidos
  86. // Para que possamos copiá-los sem testar as bandeiras
  87. // No entanto, no futuro isso pode mudar, então vamos
  88. // Apenas copie quando as bandeiras nos dizem que podemos.
  89.  
  90. if(bUpdateFlags & THROTTLE_FLAG)
  91. {
  92. unThrottleIn = unThrottleInShared;
  93. }
  94.  
  95. if(bUpdateFlags & STEERING_FLAG)
  96. {
  97. unSteeringIn = unSteeringInShared;
  98. }
  99.  
  100. if(bUpdateFlags & AUX_FLAG)
  101. {
  102. unAuxIn = unAuxInShared;
  103. }
  104.  
  105. // Limpe a cópia compartilhada de sinalizadores atualizados, já que já tomamos as atualizações
  106. // Ainda temos uma cópia local se precisarmos usá-la em bUpdateFlags
  107. bUpdateFlagsShared = 0;
  108.  
  109. interrupts(); //Nós temos cópias locais das entradas, então agora podemos fazer as interrupções de volta
  110. // Assim que as interrupções estiverem de volta, não podemos mais usar as cópias compartilhadas, a interrupção
  111. // As rotinas de serviços possuem essas e podem atualizá-las a qualquer momento. Durante a atualização, o
  112. // As cópias compartilhadas podem conter lixo. Felizmente, temos nossas cópias locais para trabalhar com :-)
  113. }
  114.  
  115. // Faça qualquer processamento a partir daqui em diante
  116. // Use apenas valores locais unAuxIn, unThrottleIn e unSteeringIn, o compartilhado
  117. //Variáveis unAuxInShared, unThrottleInShared, unSteeringInShared são sempre propriedade de
  118. // As rotinas de interrupção e não devem ser usadas em loop
  119.  
  120. // O código a seguir fornece passagem simples
  121. // Este é um bom teste inicial, o Arduino irá passar
  122. // Entrada do receptor como se o Arduino não estivesse lá.
  123. // Isso deve ser usado para confirmar o circuito e a alimentação
  124. // Antes de tentar qualquer processamento personalizado em um projeto.
  125.  
  126. // Estamos verificando se o valor do canal mudou, isto é indicado
  127. // Pelas bandeiras. Para o simples passe, realmente não precisamos deste cheque,
  128. // Mas para um projeto mais complexo, onde um novo sinal requer um processamento significativo
  129. // Isso nos permite apenas calcular novos valores quando temos novas entradas, em vez de
  130. // Em todos os ciclos.
  131. if(bUpdateFlags & THROTTLE_FLAG)
  132. {
  133. if(servoThrottle.readMicroseconds() != unThrottleIn)
  134. {
  135. servoThrottle.writeMicroseconds(unThrottleIn);
  136. }
  137. }
  138.  
  139. if(bUpdateFlags & STEERING_FLAG)
  140. {
  141. if(servoSteering.readMicroseconds() != unSteeringIn)
  142. {
  143. servoSteering.writeMicroseconds(unSteeringIn);
  144. }
  145. }
  146.  
  147. if(bUpdateFlags & AUX_FLAG)
  148. {
  149. if(servoAux.readMicroseconds() != unAuxIn)
  150. {
  151. servoAux.writeMicroseconds(unAuxIn);
  152. }
  153. }
  154.  
  155. bUpdateFlags = 0;
  156. }
  157.  
  158.  
  159. // Rotina de serviço de interrupção simples
  160. void calcThrottle()
  161. {
  162. // Se o pino estiver alto, é uma margem ascendente do pulso do sinal, de modo a registrar seu valor
  163. if(digitalRead(THROTTLE_IN_PIN) == HIGH)
  164. {
  165. ulThrottleStart = micros();
  166. }
  167. else
  168. {
  169. // Senão deve ser uma borda descendente, então vamos dar o tempo e subtrair o tempo da margem ascendente
  170. // Isso dá uso do tempo entre os limites ascendente e descendente, isto é, a duração do pulso.
  171. unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);
  172. // Use set the throttle flag para indicar que um novo sinal de aceleração foi recebido
  173. bUpdateFlagsShared |= THROTTLE_FLAG;
  174. }
  175. }
  176.  
  177. void calcSteering()
  178. {
  179. if(digitalRead(STEERING_IN_PIN) == HIGH)
  180. {
  181. ulSteeringStart = micros();
  182. }
  183. else
  184. {
  185. unSteeringInShared = (uint16_t)(micros() - ulSteeringStart);
  186. bUpdateFlagsShared |= STEERING_FLAG;
  187. }
  188. }
  189.  
  190. void calcAux()
  191. {
  192. if(digitalRead(AUX_IN_PIN) == HIGH)
  193. {
  194. ulAuxStart = micros();
  195. }
  196. else
  197. {
  198. unAuxInShared = (uint16_t)(micros() - ulAuxStart);
  199. bUpdateFlagsShared |= AUX_FLAG;
  200. }
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement