#include <inttypes.h> #include <stdbool.h> #include <avr/io.h> #include "SDI12.h" // 0.1 header file for this library #define _BUFFER_SIZE 64 // 0.2 max RX buffer size #define DISABLED 0 // 0.3 value for DISABLED state #define ENABLED 1 // 0.4 value for ENABLED state #define HOLDING 2 // 0.5 value for DISABLED state #define TRANSMITTING 3 // 0.6 value for TRANSMITTING state #define LISTENING 4 // 0.7 value for LISTENING state #define SPACING 830 // 0.8 bit timing in microseconds #define PHIGH PORTB7; #define PLOW PORTB7; #define INMODE PORTB7; #define OUTMODE PORTB7; //SDI12 *SDI12__activeObject = NULL; // 0.9 pointer to active SDI12 object uint8_t _dataPin; // 0.10 reference to the data pin bool _bufferOverflow; // 0.11 buffer overflow status // See section 0 above. // 1.1 - max buffer size char _rxBuffer[_BUFFER_SIZE]; // 1.2 - buff for incoming uint8_t _rxBufferHead = 0; // 1.3 - index of buff head uint8_t _rxBufferTail = 0; // 1.4 - index of buff tail // 2.1 - sets the state of the SDI-12 object. void SDI12_setState(uint8_t state){ if(state == HOLDING){ pinMode(_dataPin,OUTPUT); digitalWrite(_dataPin,LOW); *digitalPinToPCMSK(_dataPin) &= ~(1<<digitalPinToPCMSKbit(_dataPin)); return; } if(state == TRANSMITTING){ pinMode(_dataPin,OUTPUT); noInterrupts(); // supplied by Arduino.h, same as cli() return; } if(state == LISTENING) { digitalWrite(_dataPin,LOW); pinMode(_dataPin,INPUT); interrupts(); // supplied by Arduino.h, same as sei() *digitalPinToPCICR(_dataPin) |= (1<<digitalPinToPCICRbit(_dataPin)); *digitalPinToPCMSK(_dataPin) |= (1<<digitalPinToPCMSKbit(_dataPin)); } else { // implies state==DISABLED digitalWrite(_dataPin,LOW); pinMode(_dataPin,INPUT); *digitalPinToPCMSK(_dataPin) &= ~(1<<digitalPinToPCMSKbit(_dataPin)); if(!*digitalPinToPCMSK(_dataPin)){ *digitalPinToPCICR(_dataPin) &= ~(1<<digitalPinToPCICRbit(_dataPin)); } } } // 2.2 - forces a HOLDING state. void SDI12_forceHold(){ setState(HOLDING); } // 3.1 Constructor SDI12_SDI12(uint8_t dataPin){ _bufferOverflow = false; _dataPin = dataPin; } // 3.2 Destrutor SDI12_dest(){ setState(DISABLED); } // 3.3 Begin void SDI12_begin() { setState(HOLDING); setActive(); } // 3.4 End void SDI12_end() { setState(DISABLED); } // 4.1 - this function wakes up the entire sensor bus void SDI12_wakeSensors(){ SDI12_setState(TRANSMITTING); SDI12_digitalWrite(_dataPin, HIGH); delayMicroseconds(12100); digitalWrite(_dataPin, LOW); delayMicroseconds(8400); } // 4.2 - this function writes a character out on the data line void SDI12_writeChar(uint8_t out) { out |= (parity_even_bit(out)<<7); // 4.2.1 - parity bit digitalWrite(_dataPin, HIGH); // 4.2.2 - start bit delayMicroseconds(SPACING); for (byte mask = 0x01; mask; mask<<=1){ // 4.2.3 - send payload if(out & mask){ digitalWrite(_dataPin, LOW); } else{ digitalWrite(_dataPin, HIGH); } delayMicroseconds(SPACING); } digitalWrite(_dataPin, LOW); // 4.2.4 - stop bit delayMicroseconds(SPACING); } // 4.3 - this function sends out the characters of the String cmd, one by one void SDI12_sendCommand(String cmd){ wakeSensors(); // wake up sensors for (int i = 0; i < cmd.length(); i++){ writeChar(cmd[i]); // write each characters } setState(LISTENING); // listen for reply } /* ============= 5. Reading from the SDI-12 object. ===================*/ // 5.1 - reveals the number of characters available in the buffer int SDI12_available() { if(_bufferOverflow) return -1; return (_rxBufferTail + _BUFFER_SIZE - _rxBufferHead) % _BUFFER_SIZE; } // 5.2 - reveals the next character in the buffer without consuming int SDI12_peek() { if (_rxBufferHead == _rxBufferTail) return -1; // Empty buffer? If yes, -1 return _rxBuffer[_rxBufferHead]; // Otherwise, read from "head" } // 5.3 - a public function that clears the buffer contents and // resets the status of the buffer overflow. void SDI12_flush() { _rxBufferHead = _rxBufferTail = 0; _bufferOverflow = false; } // 5.4 - reads in the next character from the buffer (and moves the index ahead) int SDI12_read() { _bufferOverflow = false; //reading makes room in the buffer if (_rxBufferHead == _rxBufferTail) return -1; // Empty buffer? If yes, -1 uint8_t nextChar = _rxBuffer[_rxBufferHead]; // Otherwise, grab char at head _rxBufferHead = (_rxBufferHead + 1) % _BUFFER_SIZE; // increment head return nextChar; // return the char } // 6.1 - a method for setting the current object as the active object bool SDI12_setActive() { if (_activeObject != this) { setState(HOLDING); _activeObject = this; return true; } return false; } // 6.2 - a method for checking if this object is the active object bool SDI12_isActive() { return this == _activeObject; } // 6.1 - Passes off responsibility for the interrupt to the active object. inline void SDI12_handleInterrupt(){ if (_activeObject) _activeObject->receiveChar(); } // 6.2 - Quickly reads a new character into the buffer. void SDI12_receiveChar() { if (digitalRead(_dataPin)) // 6.2.1 - Start bit? { uint8_t newChar = 0; // 6.2.2 - Make room for char. delayMicroseconds(SPACING/2); // 6.2.3 - Wait 1/2 SPACING for (uint8_t i=0x1; i<0x80; i <<= 1) // 6.2.4 - read the 7 data bits { delayMicroseconds(SPACING); uint8_t noti = ~i; if (!digitalRead(_dataPin)) newChar |= i; else newChar &= noti; } delayMicroseconds(SPACING); // 6.2.5 - Skip the parity bit. delayMicroseconds(SPACING); // 6.2.6 - Skip the stop bit. // 6.2.7 - Overflow? If not, proceed. if ((_rxBufferTail + 1) % _BUFFER_SIZE == _rxBufferHead) { _bufferOverflow = true; } else { // 6.2.8 - Save char, advance tail. _rxBuffer[_rxBufferTail] = newChar; _rxBufferTail = (_rxBufferTail + 1) % _BUFFER_SIZE; } } } //6.3 #if defined(PCINT0_vect) ISR(PCINT0_vect){ SDI12_handleInterrupt(); } #endif #if defined(PCINT1_vect) ISR(PCINT1_vect){ SDI12_handleInterrupt(); } #endif #if defined(PCINT2_vect) ISR(PCINT2_vect){ SDI12_handleInterrupt(); } #endif #if defined(PCINT3_vect) ISR(PCINT3_vect){ SDI12_handleInterrupt(); } #endif
#include "msp430x21x2.h" #define PWM_OUTPUT 0x03 #define DUTY_CYCLE TA0CCR2 #define MAX_LIMIT 300 /* #define no_of_samples 1 #define duty_cycle_limit 1000 #define temp_sensor 0xA000 #define panel_selection_cutoff 250 */ #define PV_VOLTAGE INCH_0 #define PV_CURRENT INCH_1 #define BATT_VOLTAGE INCH_2 #define BATT_CURRENT INCH_3 #define UPPER_CRG_LVL 0x0105 // 0x00FF // 0x00F5 //0x023A #define LOWER_CRG_LVL ...
Comments
Post a Comment