Skip to content

Instantly share code, notes, and snippets.

@kuc-arc-f
Created August 20, 2017 04:12
Show Gist options
  • Save kuc-arc-f/e5a53f1ed64bedfd184c5eec30a835f1 to your computer and use it in GitHub Desktop.
Save kuc-arc-f/e5a53f1ed64bedfd184c5eec30a835f1 to your computer and use it in GitHub Desktop.
RN4020 +atmega328 BLE driver, with voltage check/BLE public address version
/*
SoftwareSerial, RN4020 BLE (Low Power version)
with Central= raspBerryPi , pubAddr /check-voltage version
v 0.9.01
date: 2017/08/20
*/
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(5, 6); /* RX:D5, TX:D6 */
String mBuff="";
const int mVoutPin = 0;
const int mA1_Pin =1;
const int mPinBLE =8;
const int mOK_CODE=1;
const int mNG_CODE=0;
uint32_t mTimer_runMax= 0;
const int mNextSec = 300; //Sec
// const int mNextSec = 600; //Sec
const int mMax_runSec= 5; //Sec
const int mMode_RUN = 1;
const int mMode_WAIT = 2;
int mMode =0;
const int mMaxGap=25;
// LOW power
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
volatile int wdt_cycle;
//
int get_voltage5V(){
int ret=0;
unsigned long reading = 0;
const int iMax =10;
//Serial.println("#rd.start=" + String(millis() ));
//pre-read
for (int i=0; i<iMax ; i++) {
int pre = analogRead(mA1_Pin );
}
for (int i=0; i<iMax ; i++) {
int sensorValue = analogRead(mA1_Pin );
reading +=sensorValue ;
delay(10);
}
//Serial.println("#rd.end=" + String(millis() ));
int iAvenum=reading / iMax;
// Serial.println("iAvenum=" + String(iAvenum ) );
int val = map(iAvenum, 0, 1023, 0, 3300);
//Serial.println( "val="+ String(val ) );
float fRitu = 47000 + 10000;
fRitu = fRitu / 10000;
//Serial.println( "fRitu="+ String(fRitu ) );
float vol_5V = (float)val * fRitu ;
// Serial.println("vol_5V=" + String(vol_5V ) );
ret= (int)vol_5V;
return ret;
}
//
long convert_Map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
//
String convert_hex(String src){
String sRet="";
// int iLen=src.length();
// int iLen=mMaxGap *2;
char sRead[mMaxGap+1 ];
sprintf(sRead, "%s", src.c_str() );
for(int i=0; i< mMaxGap ; i++){
char cBuff[2+1];
sprintf( cBuff, "%02x", sRead[i] );
String sBuff=String(cBuff );
// sRet += sBuff;
sRet.concat(sBuff );
// Serial.println(cBuff );
}
// Serial.println ( "sRet="+ sRet );
return sRet;
}
//
// reading LM60BIZ
int getTempNum(){
int iRet=0;
// float fSen = 0;
unsigned long reading = 0;
for (int i=0; i<10; i++) {
int iTmp = analogRead(mVoutPin);
//Serial.print("get.iTmp=");
//Serial.println(iTmp);
reading += iTmp;
delay(50);
}
int SValue= reading / 10;
int voltage=convert_Map(SValue, 0, 1000, 0,3300); // V
// Serial.println("SValue="+ String(SValue) +" , voltage=" +String(voltage ) );
int iTemp = (voltage - 424) / 6.25; //電圧値を温度に変換, offset=425
iRet= iTemp;
return iRet;
}
//
int Is_resWait(String value, uint32_t maxMsec ){
int ret= mNG_CODE;
uint32_t tm_maxWait=millis();
int iLen= value.length();
String sBuff="";
int iBool=1;
while(iBool ){
while( mySerial.available() ){
char c= mySerial.read();
Serial.print( c );
if( (c != 0x0a ) && (c != 0x0d ) ){
sBuff.concat(c );
}
} //end_while
if( (int )sBuff.length() >= iLen ){ iBool=0; }
delay(100);
uint32_t tmMax =millis() -tm_maxWait;
if(tmMax > (uint32_t)maxMsec ){
Serial.println("#Error-Is_resWait:maxSec!");
iBool=0;
}
}//end_while_1
Serial.println("");
if(sBuff.length() < 1){ return ret; }
int iLenBuff= sBuff.length();
int iSt=iLenBuff -(iLen);
Serial.println("iLenBuff="+ String(iLenBuff)+",iSt="+ String(iSt) ) ;
String sRecv = sBuff.substring(iSt , iLen );
Serial.println( "sBuff="+ sBuff+ " ,sRecv="+ sRecv );
if(sRecv == value ){
ret= mOK_CODE;
}
return ret;
}
//
void proc_getSSerial(){
while( mySerial.available() ){
char c= mySerial.read();
Serial.print( c );
} //end_while
}
int mCounter=0;
//
void proc_sendCmd(){
int iWaitTm= 5000;
//int iLenBuff=(mMaxGap * 2) + 2+1;
int iLenBuff=(mMaxGap * 2) + 3 +1;
char cRead[25 +1];
char cBuff[iLenBuff ];
int iSenNum= getTempNum();
int vol= get_voltage5V();
Serial.println("iSenNum=" + String(iSenNum) );
//sprintf(cRead , "%05d%05d%05d%05d%05d", iSenNum ,0 ,0 , 0, 0 );
sprintf(cRead , "%05d%05d%05d%05d%05d", iSenNum ,vol ,0 , 0, 0 );
Serial.println("cRead="+ String(cRead ));
String sRead= convert_hex( String(cRead) );
Serial.println("Hex=" +sRead);
sprintf(cBuff , "N,%s\r", sRead.c_str() );
//N
Serial.println( "#Start N, cBuff="+ String(cBuff) );
mySerial.print(String(cBuff) );
if( Is_resWait("AOK", iWaitTm ) == mNG_CODE ){ return; }
else{Serial.println("#OK SN" ); };
proc_getSSerial();
//R
//Serial.println( "#Start R" );
//mySerial.print("R,1\r");
//delay(1000);
//if( Is_resWait("RebootCMD", iWaitTm ) == mNG_CODE ){ return; }
//else{Serial.println("#OK R1" ); };
//proc_getSSerial();
//A
Serial.println( "#Start A" );
// mySerial.print("A\r");
mySerial.print("A,0064,07D0\r"); //100msec, total= 2000mSec
if( Is_resWait("AOK", iWaitTm ) == mNG_CODE ){ return; }
else{Serial.println("#OK A" ); };
proc_getSSerial();
mCounter= mCounter+1;
wait_forSec(3 );
}
//
void wait_forSec(int wait){
for(int i=0; i<wait; i++){
delay(1000);
Serial.println("#wait_forMsec: "+ String(i) );
}
}
//
void setup() {
mMode = mMode_RUN;
pinMode(mPinBLE ,OUTPUT);
Serial.begin( 9600 );
mySerial.begin( 9600 );
Serial.println("#Start-setup-SS");
setup_watchdog(6 ); // WDT setting
//wait
delay(1000);
//wait_forSec(3);
proc_getSSerial(); //clear-buff
}
//
void loop() {
//const int iWait =2000;
// Serial.println( "mTimer="+ String(mTimer) + ",millis=" + String(millis()) );
if(mMode ==mMode_RUN){
if(mTimer_runMax <= 0 ){
mTimer_runMax = ((uint32_t)mMax_runSec * 1000) + millis();
digitalWrite(mPinBLE, HIGH);
delay(1000);
}
if(millis() < mTimer_runMax){
digitalWrite(mPinBLE, HIGH);
proc_sendCmd();
}else{
mTimer_runMax=0;
digitalWrite(mPinBLE,LOW );
mMode = mMode_WAIT;
}
}else{
mMode = mMode_RUN;
for(int i=0; i< mNextSec ; i++){
system_sleep(); // power down ,wake up WDT
//Serial.print("i=");
//delay(15);
//Serial.println(i);
//delay(15);
}
}
}
//
void system_sleep() {
cbi(ADCSRA,ADEN); // ADC power off
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // power down mode
sleep_enable();
sleep_mode(); // sleep
sleep_disable(); // WDT time up
sbi(ADCSRA,ADEN); // ADC ON
}
// WDT setting, param : time
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) { //
byte bb;
int ww;
if (ii > 9 ) ii=9;
bb=ii & 7;
if (ii > 7) bb|= (1<<5);
bb|= (1<<WDCE);
ww=bb;
MCUSR &= ~(1<<WDRF);
// start timed sequence
WDTCSR |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCSR = bb;
WDTCSR |= _BV(WDIE);
} //setup_watchdog
ISR(WDT_vect) { // WDT, time Up process
wdt_cycle++;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment