/** * Universal remote controller * * Author: Jan Dvořák z Vozerovic * E-mail: dvorkaman@gmail.com * Web: dvorkaman.asp2.cz * Created: 2013 */ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define CALIBRATION // libraries #include "stdio.h" #define _define_bool_ 0x01 #include "libInit.c" #include "libGPIO.c" #include "libTime.c" #include "libSwitch.c" #include "libUSART.c" #include "libAnalog.c" #include "libUtils.c" #include "libXbee.c" #include "libRemote.c" // timing #define PROCESS_INPUT_EACH 125 // ms - 8times per second // analog inputs #define ANALOG_INPUTS 6 #define LIB_ANALOG_MINIMAL_CHANGE 8 #define TRIMMER_ONE_MIDDLE_POSITION 512 //stear forwards / backwards - middle position #define TRIMMER_ONE_MIN_POSITION 392 // - min position #define TRIMMER_ONE_MAX_POSITION 626 // - max position #define TRIMMER_SIX_MIDDLE_POSITION 536 //stear left / right - middle position #define TRIMMER_SIX_MIN_POSITION 422 // - min position #define TRIMMER_SIX_MAX_POSITION 658 // - max position #define TRIMMER_STEAR_BLIND_SPOT_SIZE 48 //size around middle position where output value is constant with value TRIMMER_STEAR_MAX_VALUE / 2 volatile uint16_t analogInputs[ANALOG_INPUTS]; // buffer from ADC filled using DMA libAnalogFilter af; // filter to the input values libAnalog tr1, tr2, tr3, tr4, tr5, tr6; // analog input trimmers using filtered values u16 analogValues[ANALOG_INPUTS]; // used when reading analog collection bool analogValuesChanged[ANALOG_INPUTS]; // used when reading analog collection // digital inputs #define LIB_SWITCH_MINIMAL_TIME 10 // ms #define BUTTON_INPUTS 4 #define SWITCH_INPUTS 6 // leds #define LED_GPIO GPIOA #define LED_RED GPIO_Pin_6 #define LED_GREEN GPIO_Pin_7 /** * Show error */ void showError(u32 onTime, u32 offTime) { while (1) { writeOutputPin(LED_GPIO, LED_RED, Bit_SET); delayMs(onTime); writeOutputPin(LED_GPIO, LED_RED, Bit_RESET); delayMs(offTime); } } void TxFull() { showError(1000, 1000); } /** * Main method */ int main(void) { /** * DECLARATION */ u8 i; systemTime now; bool bval; systemTime lastInputsProcessed = getClock(); // Analog input usage u8 trimmerCommands[ANALOG_INPUTS] = {REM_COMMNAND_TRIMMER1, REM_COMMNAND_TRIMMER2, REM_COMMNAND_TRIMMER3, REM_COMMNAND_TRIMMER4, REM_COMMNAND_TRIMMER5, REM_COMMNAND_TRIMMER6}; // xbee libXbee xbee; u8 xbeeCommand[REM_COMMAND_LENGTH]; // buttons libSwitch bt[BUTTON_INPUTS]; u8 buttonCommands[BUTTON_INPUTS] = {REM_COMMNAND_BUTTON1, REM_COMMNAND_BUTTON2, REM_COMMNAND_BUTTON3, REM_COMMNAND_BUTTON4}; bool lastButtonStates[BUTTON_INPUTS] = {FALSE, FALSE, FALSE, FALSE}; // switches libSwitch sw[SWITCH_INPUTS]; u8 switchCommands[SWITCH_INPUTS] = {REM_COMMNAND_SWITCH1, REM_COMMNAND_SWITCH2, REM_COMMNAND_SWITCH3, REM_COMMNAND_SWITCH4, REM_COMMNAND_SWITCH5, REM_COMMNAND_SWITCH6}; bool lastSwitchStates[SWITCH_INPUTS] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; // status leds BitAction ledRed = (BitAction)1; // transmitter buffer libRemoteTx remoteTx; u16 remoteCommand; /** * INITIALIZATION */ initialize(2); // gpio A + B initializeClock(); // init 6 trimmers for analog inputs initializeInputAnalogPin(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5); inicializeADC(0, 5, (uint32_t) &analogInputs); // A0 = port 0; A5 = port 5 af = initializeAnalogFilter(ANALOG_INPUTS, analogInputs); tr1 = initializeAnalogOutputRange(&af, 0, TRIMMER_STEAR_BLIND_SPOT_SIZE, LIB_ANALOG_MINIMAL_CHANGE, TRIMMER_ONE_MIN_POSITION, TRIMMER_ONE_MAX_POSITION, TRIMMER_ONE_MIDDLE_POSITION, ANALOG_VALUE_RANGE); tr2 = initializeAnalogOutputRange(&af, 1, 0, LIB_ANALOG_MINIMAL_CHANGE, ANALOG_MIN_POSITION, ANALOG_MAX_POSITION, ANALOG_MIDDLE_POSITION, ANALOG_VALUE_RANGE); tr3 = initializeAnalogOutputRange(&af, 2, 0, LIB_ANALOG_MINIMAL_CHANGE, ANALOG_MIN_POSITION, ANALOG_MAX_POSITION, ANALOG_MIDDLE_POSITION, ANALOG_VALUE_RANGE); tr4 = initializeAnalogOutputRange(&af, 3, 0, LIB_ANALOG_MINIMAL_CHANGE, ANALOG_MIN_POSITION, ANALOG_MAX_POSITION, ANALOG_MIDDLE_POSITION, ANALOG_VALUE_RANGE); tr5 = initializeAnalogOutputRange(&af, 4, 0, LIB_ANALOG_MINIMAL_CHANGE, ANALOG_MIN_POSITION, ANALOG_MAX_POSITION, ANALOG_MIDDLE_POSITION, ANALOG_MAX_POSITION); tr6 = initializeAnalogOutputRange(&af, 5, TRIMMER_STEAR_BLIND_SPOT_SIZE, LIB_ANALOG_MINIMAL_CHANGE, TRIMMER_SIX_MIN_POSITION, TRIMMER_SIX_MAX_POSITION, TRIMMER_SIX_MIDDLE_POSITION, ANALOG_VALUE_RANGE); addLibAnalogToCollection(&tr1); addLibAnalogToCollection(&tr2); addLibAnalogToCollection(&tr3); addLibAnalogToCollection(&tr4); addLibAnalogToCollection(&tr5); addLibAnalogToCollection(&tr6); // leds initializeOutputPin(LED_GPIO, LED_GREEN | LED_RED); writeOutputPin(LED_GPIO, LED_GREEN, (BitAction) 1); // put both on writeOutputPin(LED_GPIO, LED_RED, ledRed); // put both on // buttons bt[0] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_4, LIB_SWITCH_MINIMAL_TIME); bt[1] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_5, LIB_SWITCH_MINIMAL_TIME); bt[2] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_6, LIB_SWITCH_MINIMAL_TIME); bt[3] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_7, LIB_SWITCH_MINIMAL_TIME); // switches sw[0] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_10, LIB_SWITCH_MINIMAL_TIME); sw[1] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_11, LIB_SWITCH_MINIMAL_TIME); sw[2] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_12, LIB_SWITCH_MINIMAL_TIME); sw[3] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_13, LIB_SWITCH_MINIMAL_TIME); sw[4] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_14, LIB_SWITCH_MINIMAL_TIME); sw[5] = initializeSwitchMinPressTime(GPIOB, GPIO_Pin_15, LIB_SWITCH_MINIMAL_TIME); // xbee - usart 1 #ifndef CALIBRATION initializeUSART1(); xbee = initializeXBee(USART1, TRUE); #endif // output buffer remoteTx = initializeRemoteTx(); /** * MAIN LOOP */ while (1) { /* 1) Connection */ #ifndef CALIBRATION if (isXbeeConnected(&xbee) == FALSE) { if (ledRed == Bit_RESET) { ledRed = Bit_SET; // turn ON writeOutputPin(LED_GPIO, LED_RED, ledRed); } continue; } if (ledRed == Bit_SET) { ledRed = Bit_RESET; // turn OF writeOutputPin(LED_GPIO, LED_RED, ledRed); } /* 2) Write output commands */ if (isRemoteTxEmpty(&remoteTx) == FALSE && isXbeeReadyToSendCommand(&xbee) == TRUE) { remoteCommand = getRemoteTxNextCommand(&remoteTx); xbeeCommand[0] = remoteCommand >> 8; xbeeCommand[1] = remoteCommand & 0xFF; sendXbeeCommand(&xbee, xbeeCommand); } #endif /* System time */ now = getClock(); /* 3) Read inputs */ // Analog inputs if (getClockDiffInMs(lastInputsProcessed, now) >= PROCESS_INPUT_EACH && isAnalogCollectionReady() == TRUE) { // Analog getAnalogColectionValuesChanged(analogValues, analogValuesChanged); #ifdef CALIBRATION continue; #endif for (i = 0; i < ANALOG_INPUTS; i++) { if (analogValuesChanged[i] == TRUE) { if (putRemoteTxCommand(&remoteTx, trimmerCommands[i], analogValues[i]) == FALSE) { TxFull(); } } } // Buttons for (i = 0; i < BUTTON_INPUTS; i++) { bval = isSwitchPressed(&bt[i]); if (bval != lastButtonStates[i]) { if (putRemoteTxCommand(&remoteTx, buttonCommands[i], (int)bval) == FALSE) { TxFull(); } lastButtonStates[i] = bval; } } // Switches for (i = 0; i < SWITCH_INPUTS; i++) { bval = isSwitchPressed(&sw[i]); if (bval != lastSwitchStates[i]) { if (putRemoteTxCommand(&remoteTx, switchCommands[i], (int)bval) == FALSE) { TxFull(); } lastSwitchStates[i] = bval; } } // timing lastInputsProcessed = now; } } }