Пример #1
0
//=========================================================================
//----- (0000782C) --------------------------------------------------------
__myevic__ void SleepIfIdle()
{
	if ( !gFlags.firing && !NoEventTimer )
	{
		if ( ( Screen == 0 ) && ( SleepTimer == 0 ) && ( gFlags.user_idle ) )
		{
			GoToSleep();

			byte_200000B3 = 2;
			AtoProbeCount = 0;
			AtoRezMilli = 0;
			gFlags.sample_vbat = 1;
			ReadBatteryVoltage();
			if (( BatteryVoltage <= BatteryCutOff + 20 ) && !gFlags.usb_attached )
			{
				dfStatus.off = 1;
				Screen = 0;
			}
			gFlags.sample_btemp = 1;
		}
		NoEventTimer = 200;
	}
}
Пример #2
0
//=========================================================================
//----- (00000148) --------------------------------------------------------
__myevic__ void Main()
{
	InitDevices();

	InitVariables();

	// Enable chip temp sensor sampling by ADC
	if ( ISRX300 )
	{
		SYS->IVSCTL |= SYS_IVSCTL_VTEMPEN_Msk;
	}

	InitHardware();

	myprintf( "\n\nJoyetech APROM\n" );
	myprintf( "CPU @ %dHz(PLL@ %dHz)\n", SystemCoreClock, PllClock );

	SetBatteryModel();

	gFlags.sample_vbat = 1;
	ReadBatteryVoltage();

	gFlags.sample_btemp = 1;
	ReadBoardTemp();

	InitDisplay();
	MainView();
	SplashTimer = 3;

	CustomStartup();

	if ( !PD3 )
	{
		DrawScreen();
		while ( !PD3 )
			;
	}

	while ( 1 )
	{
		while ( gFlags.playing_fb )
		{
			// Flappy Bird game loop
			fbCallTimeouts();
			if ( gFlags.tick_100hz )
			{
				// 100Hz
				gFlags.tick_100hz = 0;
				ResetWatchDog();
				TimedItems();
				SleepIfIdle();
				GetUserInput();
				if ( !PE0 )
					SleepTimer = 3000;
			}
			if ( gFlags.tick_10hz )
			{
				// 10Hz
				gFlags.tick_10hz = 0;
				DataFlashUpdateTick();
			}
		}

		if ( gFlags.firing )
		{
			ReadAtoCurrent();
		}

		if ( gFlags.tick_5khz )
		{
			// 5000Hz
			gFlags.tick_5khz = 0;

			if ( gFlags.firing )
			{
				RegulateBuckBoost();
			}
		}

		if ( gFlags.tick_1khz )
		{
			// 1000Hz
			gFlags.tick_1khz = 0;

			if ( gFlags.firing )
			{
				ReadAtomizer();

				if ( ISMODETC(dfMode) )
				{
					if ( gFlags.check_mode )
					{
						CheckMode();
					}
					TweakTargetVoltsTC();
				}
				else if ( ISMODEVW(dfMode) )
				{
					TweakTargetVoltsVW();
				}
			}

			if ( dfStatus.vcom )
			{
				VCOM_Poll();
			}
		}

		if ( gFlags.tick_100hz )
		{
			// 100Hz
			gFlags.tick_100hz = 0;

			ResetWatchDog();

			if ( gFlags.read_battery )
			{
				gFlags.read_battery = 0;
			}

			TimedItems();
			SleepIfIdle();
			ReadBatteryVoltage();
			ReadBoardTemp();

			if ( gFlags.firing && BoardTemp >= 70 )
			{
				Overtemp();
			}

			if ( ISVTCDUAL )
			{
				BatteryChargeDual();
			}
			else if ( ISCUBOID || ISCUBO200 || ISRX200S || ISRX23 || ISRX300 )
			{
				BatteryCharge();
			}

			if (( gFlags.anim3d ) && ( Screen == 1 ) && ( !EditModeTimer ))
			{
				anim3d( 0 );
			}

			if ( Screen == 60 )
			{
				AnimateScreenSaver();
			}

			if ( gFlags.firing )
			{
				if ( gFlags.read_bir && ( FireDuration > 10 ) )
				{
					ReadInternalResistance();
				}

				if ( PreheatTimer && !--PreheatTimer )
				{
					uint16_t pwr;

					if ( dfMode == 6 )
					{
						pwr = dfSavedCfgPwr[ConfigIndex];
					}
					else
					{
						pwr = dfPower;
					}

					if ( pwr > BatteryMaxPwr )
					{
						gFlags.limit_power = 1;
						PowerScale = 100 * BatteryMaxPwr / pwr;
					}
					else
					{
						gFlags.limit_power = 0;
						PowerScale = 100;
					}
				}
			}

			if ( KeyTicks >= 5 )
			{
				KeyRepeat();
			}

			GetUserInput();
		}

		if ( gFlags.tick_10hz )
		{
			// 10Hz
			gFlags.tick_10hz = 0;

			DataFlashUpdateTick();
			LEDTimerTick();

			if ( gFlags.firing )
			{
				++FireDuration;

				if ( gFlags.monitoring )
				{
					Monitor();
				}
			}

			if ( ShowWeakBatFlag )
				--ShowWeakBatFlag;

			if ( ShowProfNum )
				--ShowProfNum;

			if ( !( gFlags.firing && ISMODETC(dfMode) ) )
			{
				DrawScreen();
			}

			if ( KeyTicks < 5 )
			{
				KeyRepeat();
			}
		}

		if ( gFlags.tick_5hz )
		{
			// 5Hz
			gFlags.tick_5hz = 0;

			if ( !gFlags.rtcinit && NumBatteries )
			{
				InitRTC();
			}

			if ( gFlags.firing )
			{
				if ( TargetVolts == 0 )
				{
					ProbeAtomizer();
				}
			}
			else
			{
				if
				(	!dfStatus.off
					&& Event == 0
					&& ( AtoProbeCount < 12 )
					&& ( Screen == 0 || Screen == 1 || Screen == 5 ) )
				{
					ProbeAtomizer();
				}
			}

			if ( IsClockOnScreen() )
			{
				static uint8_t u8Seconds = 61;
				S_RTC_TIME_DATA_T rtd;

				GetRTC( &rtd );

				if ( (uint8_t)rtd.u32Second != u8Seconds )
				{
					u8Seconds = (uint8_t)rtd.u32Second;
					gFlags.refresh_display = 1;
				}
			}
		}

		if ( gFlags.tick_2hz )
		{
			// 2Hz
			gFlags.tick_2hz = 0;

			gFlags.osc_1hz ^= 1;

			if ( gFlags.firing )
			{
				if ( ISMODETC(dfMode) )
				{
					DrawScreen();
				}
			}
			else
			{
				if
				(	!dfStatus.off
					&& Event == 0
					&& ( AtoProbeCount >= 12 )
					&& ( Screen == 0 || Screen == 1 || Screen == 5 ) )
				{
					ProbeAtomizer();
				}

				if ( gFlags.monitoring )
				{
					Monitor();
				}
			}
		}

		if ( gFlags.tick_1hz )
		{
			// 1Hz
			gFlags.tick_1hz = 0;

			if ( SplashTimer )
			{
				--SplashTimer;
				
				if ( !SplashTimer )
				{
					MainView();
				}
			}

			if ( !gFlags.firing && !dfStatus.off && !EditModeTimer )
			{
				if ( HideLogo )
				{
					if ( Screen == 1 )
					{
						--HideLogo;

						if ( !HideLogo )
						{
							gFlags.refresh_display = 1;
						}
					}
				}
			}
		}

		EventHandler();

	}
}
Пример #3
0
void main( void )
{                             
 
	PhasePtr = 1;
	PhaseErr = 0;    
	iTimerSOC = 0;
    
	// Declare your local variables here

	// Port A
	PORTA=0x00;
	DDRA=0x00;

	// Port B
	PORTB=0x00;
	DDRB=0x00;

	// Port C
	PORTC=0x00;
	DDRC=0xFF;

	// Port D
	PORTD = 0x00;
	DDRD=0xfc;

	// Timer/Counter 0 initialization
	//TCCR0=0x04;  //    CLK / 64
	//TCNT0=0x00;

	// Timer/Counter 1 initialization
	TCCR1A=0x00;
	TCCR1B=0x02; // CLK / 8
	TCNT1H=0xff;
	TCNT1L=0x00;

	// External Interrupt(s) initialization
	GIMSK=0x00;
	MCUCR=0x00;

	// Timer(s)/Counter(s) Interrupt(s) initialization
	TIMSK=0x04;

	// UART initialization
	UCR=0x98;   //0x18;
	UBRR=0x19;  //0x0c for 4 MHZ 0x19 for 8MHZ

	// Analog Comparator initialization
	ACSR=0x80;

	// ADC initialization
	ADMUX=ADC_VREF_TYPE;
	ADCSR=0x81;

	// Prep Commutation array for forward motion
	for( itmp = 0; itmp <= 7; itmp++ )
	{
		ActiveOut[ itmp ] = PhaseOutFWD[ itmp ];
	}
                    

	//TCNT0 = TCOUNT_0;
	TCNT1 = TCOUNT_1;

       
    	PORTC = 0;    
	PORTC = PhaseOutFWD[ 0 ];
	PORTC = PhaseOutFWD[ 0 ];

	PORTC = 0x40 | PhaseOutFWD[ 0 ];
	PORTC = 0x40 | PhaseOutFWD[ 0 ];
	PORTC = 0x00;                  
     	
     	// Global enable interrupts

	#asm("sei")

	LEDbyte = 0;
	OldLEDbyte = 0;
	      
	
	ComSequence = 0;
	DriveEnable = 1;
	
	CurrentLimitByte = 0;
	OvrTemp = 0;             
	
	isecTmr = 0;
	isecTimer = 0;  
	isecTmrWatts = 0;
		
	AutoUpdate = 1;
	iMaxEconoSpeed = 1025; 
     	BatteryPowerLow = 0;
	
	//PORTD = 0x00;

	MaxWattSeconds = __MAX_WATT_SECONDS; //1400000;
	
	sprintf( ComStr, _SOFTWARE_VERSION );
	ComSend( ComStr );
	
	// Turn off all lights...
	for( itmp = 0; itmp <= 5; itmp++ )
	{
		WriteDataToConsoleLEDS( SOC_LEDS[ itmp ] );
		itrDelay = 0;
		while( itrDelay < TIEMR_LED_SCAN ) 
		{
		} 
	 	
		//Read Phase Current
		AdcTempVal = read_adc( 1 );  
		iPhaseZero = AdcTempVal;
		AdcTempVal = read_adc( 1 );  
	         
		iPhaseZero = iPhaseZero + AdcTempVal;
		iPhaseZero = iPhaseZero / 2; 
		iPhaseZeroPoints[ itmp ] = iPhaseZero;
	}
	
       
	// Turn on all lights...
	WriteDataToConsoleLEDS( 0x00 );

	//////////////////////////////////////////////////////////////
	// Startup Flash lights... and Check the Battery Voltage...

	// Read Battery Voltage      
	BatteryVoltage = ReadBatteryVoltage();	      	

	itrDelay = 0;
	while( itrDelay < TIMER_HALF_SECOND ) 
	{
		
	}       
	// Read Battery Voltage      
	BatteryVoltage = BatteryVoltage + ReadBatteryVoltage();
	BatteryVoltage = BatteryVoltage / 2;
	                                
	
	//check low voltage on startup...
	// if voltage is too low, disable the bike...
	if( BatteryVoltage < __MIN_STARTUP_VOLTAGE )
	{
		// if battery is weak, shut it off ...                  
		sprintf( ComStr, "Low Voltage\r\n" );
		ComSend( ComStr );
		
     		ShutdownSystem();
     	}                           

//	sprintf( ComStr, "BV,%d,", BatteryVoltage );
  //	ComSend( ComStr );
 	
 	
	// do New cruise control init here...
	CruiseMode = 0;  // deefault is performance mode...
	if(( PINB & 0x08 ) != 0 ) // j5 is shorted economy mode
	{
	 	CruiseMode = 1;
	}
	
	ReadWattSecondsFromEEPROM();          
	CurrentWattSeconds = SavedWattSeconds;	
	// Reset watt / second counting... 
	// calculate the state of charge on the battery...
	if(( PINB & 0x10 ) == 0 ) // j6 is shorted = SLA mode
	{       
        	if(( BatteryVoltage > __NEW_SLA_VOLTAGE )&&( SavedWattSeconds < __USED_WATT_SECONDS ))  // consider this battery new...
		{      
			//Reset the Watt / Second counter here...
	 		CurrentWattSeconds = MaxWattSeconds;
		}
	}
	else
	{
        	if(( BatteryVoltage > __NEW_NIMH_VOLTAGE )&&( SavedWattSeconds < __USED_WATT_SECONDS ))  // consider this battery new...
		{
		 	//Reset the Watt / Second counter here...
		 	CurrentWattSeconds = MaxWattSeconds;		 	
		}	
	}	
	
	LowBatteryVoltage = __LOW_BATTERY_VOLTAGE;		


	// SHOW THE CURRENT STATE OF CHARGE ON THE DISPLAY
	LEDStatus = CalcStateOfChargeForConsole();
	

	calcLEDbyte = SOC_LEDS[ LEDStatus ]; 
	LEDbyte = calcLEDbyte;
	OldLEDbyte = LEDbyte;
		
	WriteDataToConsoleLEDS( LEDbyte );
	
	// start of main loop
	while( 1 )
      	{         
                // timer routine for "real time" clock, calculated second...
		isecTmr++;
		if( isecTmr > _CALC_SECOND )
 		{
			isecTimer++;
			isecTmrWatts++;
				
   			isecTmr = 0;
     		}                   		
		
      		CurrentLimitByte = 0;  // clear out the current limit control
      		if(( PINB & 0x08 ) != 0 ) // j5 is shorted economy mode
		{                
		 	CurrentLimitByte = 0x80;
		 	PhaseErr = 0;
		}

      		// Read The Throttle Demand 
	      	AdcPWMVal = read_adc( 7 );
      		if( AdcPWMVal > 700 )
	      	{
      			AdcPWMVal = 0;
	      	}                           
	      	if( AdcPWMVal > 511 )
	      	{
	      	 	AdcPWMVal = 511;
	      	}
      		ftmp = AdcPWMVal;
	      	vtmp = (float)(512 - ftmp);
      		vtmp = 1 / vtmp;
	      	ftmp = sqrt( vtmp );
      		ftmp = (ftmp * 360) - 16;
		if( ftmp < 0 )
		{
			ftmp = 0;
		}      	
      	
		itmp = (int)ftmp;     	
      	
	      	//itmp = AdcPWMVal>>2;
      		if( itmp > 63  ) //;;__PWM_RES_TOTAL )
      			itmp = 63; //__PWM_RES_TOTAL;
	        
	        //	oldPWMVal = tmpPWMVal;	
      		tmpPWMVal = ( unsigned char )itmp & 0x3f;
      	 
	 	// do the Speed calculations here.
		vtmp = iMotorSpeed;
		ftmp = TIMER_FREQ / vtmp;
		ftmp = ftmp * 15; // 4 halls / rev 60 revs / sec = RPM
		iMotorRPM = (int)ftmp;  

		if( iMotorRPM < 30 )
		{
			iMotorRPM = 0;
		}  
	
	
		//if(( tmpPWMVal > 6 )&&( iMotorRPM < 75 ))  // 
		if( iMotorRPM < 75 )
		{                     
			CurrentLimitByte = 0xc0; //CurrentLimitByte | 0x40;  // set at lowest limit...
		}                         
      	
	      	// Read Battery Voltage      
 	      	AvgBatteryVoltage = AvgBatteryVoltage + ReadBatteryVoltage();
	      	
	      	if(( ComSequence == 0 )||( ComSequence == 4 ))
	      	{
	      	 	BatteryVoltage = ( AvgBatteryVoltage / 4 ) + 25;	      	
	      	 	AvgBatteryVoltage = 0;
		}
		
		// if batter is too low start timer to shut it off...
	      	if( BatteryVoltage < LowBatteryVoltage )
      		{
      	 		DriveEnable++;
	      	}
      		else
	      	{      
      			if( DriveEnable < _MAX_LOW_VOLTAGE_TIME )
			{
	    	 		DriveEnable = 0;
		 	}
      		}	
      	
	      	//Read Phase Current
      		AdcTempVal = read_adc( 1 );     		
	      	iPhaseCurrent = AdcTempVal - iPhaseZeroPoints[ LEDStatus ];
		if( iPhaseCurrent < 0 )
		{
			iPhaseCurrent = 0;
		}
		
	      	ftmp = iPhaseCurrent;
	      	//PhaseCurrent = iPhaseCurrent;
	      	
                if( ftmp > 36 )
                {
                 	ftmp = ftmp * 0.9333;
                }
                BatteryCurrent = ftmp;
	      	if( BatteryCurrent > 52 )
	      	{
	      		BatteryCurrent = 52;
	      	}	      	
	      	if( BatteryCurrent <= 1 )
	      	{
	      		BatteryCurrent = 0;
	      	}
     

		// Caclulate heat sink temperature 
		AdcTempVal = read_adc( 2 ); 
		HeatSinkTemp = ConvertTempSensor( AdcTempVal );
    
    		if(( HeatSinkTemp > 62 )||( OvrTemp == 1 ))
	    	{        
                        OvrTemp = 1;
			CurrentLimitByte = 0xc0;
			if( tmpPWMVal > 27 )
			{
				tmpPWMVal = 27;
//				CurrentLimitByte = 0xc0;  // set at lowest limit...
			}		
    			// too hot... shut it off completely
    			if( HeatSinkTemp > 75 )
	    		{
    				tmpPWMVal = 0;
    			} 
    		}
    		if( HeatSinkTemp < 60 )
    		{
 	 	 	OvrTemp = 0;
    		}

                
    		
    		// do Throttle Reprofileing here
		if(( iMotorRPM > 300 )&&( iMotorRPM < 650 )) //900 ))
		{
		 	ftmp = iMotorRPM - 300;
		 	ftmp = ftmp / 15; // down to 37
		 	tmpChar = 63 - (char)ftmp;
 			if( tmpChar < tmpPWMVal )
 			{
 			 	tmpPWMVal = tmpChar;
 			}	 	
		}        
		if(( iMotorRPM >= 650 )&&( iMotorRPM < 1700 )) //if(( iMotorRPM >= 900 )&&( iMotorRPM < 1400 ))
		{
		 	ftmp = iMotorRPM - 650;  // 900
		 	ftmp = ftmp / 44; //34;
		 	tmpChar = 39 + (char)ftmp;
 			if( tmpChar < tmpPWMVal )
 			{
 			 	tmpPWMVal = tmpChar;
 			}	 	
		}

	      	// Calculate Battery Temperature
     	        /*
  		AdcTempVal = read_adc( 6 ); 
		BatteryTemp = ConvertTempSensor( AdcTempVal ); 	
      	        */
      	                     
      		if( AutoUpdate == 1 )
			OutputComData();	  
	  
		// perform delay for RS-232 output...
		itrDelay = 0;
		while( itrDelay < COM_SEQ_FREQ ) // )
		{
		}
		
		ComSequence++;
		if( ComSequence > 7 )
		{
			ComSequence = 0;
		}	                                                

		CalcCruiseControl();

	 	// Check low voltage here... 
 		if( DriveEnable >= _MAX_LOW_VOLTAGE_TIME )
	 	{
 		   	tmpPWMVal = 0; 
 		   	DriveEnable = _MAX_LOW_VOLTAGE_TIME;
			
			// shut the drive off
			ShutdownSystem();
	 	}      


		// set the throttle to the new value...		
		cPWMVal = tmpPWMVal;
		
		
		// count up the watts used every second and subtract from the total 
		// to calculate the state of charge...
		iTimerSOC++;		
		if( iTimerSOC > 15 )
		{         
    			// Calculate the Watts / 0.5 seconds / power consumption...
    			ftmp = BatteryVoltage / 100;
    			CurrentWattSeconds = CurrentWattSeconds - ((long)( BatteryCurrent ) * ftmp);
                	if( CurrentWattSeconds < 0 )
	                {
        	        	CurrentWattSeconds = 0;
                	} 
    		
		
		 	iTimerSOC = 0;
		 	
			LEDStatus = CalcStateOfChargeForConsole();

			calcLEDbyte = SOC_LEDS[ LEDStatus ];
			
		}
	       	OldLEDbyte = LEDbyte;	
                LEDbyte = calcLEDbyte;

		// make the lowest voltage blink here...
	     	if( calcLEDbyte == 0 )
	     	{       
		     	if( ComSequence < 2 )
	     		{       
	     			LEDbyte = 0x01;
	   		}
	     		else
	     		{
	     			LEDbyte = 0;
	     		}
       		}
       		else if( OvrTemp == 1 )
	     	{       
		     	if(( ComSequence & 0x03 ) == 1 )
	     		{       
	     			LEDbyte = calcLEDbyte;
	     			
				if( calcLEDbyte == 0 )
				{               
	     				LEDbyte = 0x01;
	   			}
	     		}
	     		else
	     		{
	     			LEDbyte = 0;
	     		}
       		}
       		       		                
		if( isecTmrWatts > 10 )
		{
		 	isecTmrWatts = 0;
		 	OldLEDbyte = 0; // update the LEDS every 10 seconds
		 	SaveWattSecondsToEPPROM();		 	
		}
       		       		
		// do led routines here...
	      	if( LEDbyte != OldLEDbyte )
	     	{
     		        // voltage is really low.... blink the red light...
#ifndef _DEBUG_FREQ_OUTPUT
       			WriteDataToConsoleLEDS( LEDbyte );
#endif

	     	}   	

		// Apply Current limit data here...                          
	     	tmpChar = PORTD;
	     	tmpChar = tmpChar & 0x3f;
	     	tmpChar = tmpChar | CurrentLimitByte;
		PORTD = tmpChar;
		
		
		// auto shut down timer and control
		if(( cPWMVal > 0 )&&( iMotorRPM > 0 ))
		{
			isecTimer = 0;
		}
		
		if( isecTimer > AUTO_SHUTOFF_TIME )
		{
  			ShutdownSystem();	
		}
			
        	// check com port and service any command there...
   		itmp = RecByteRdy;
		RecByteRdy = 0;
		if( itmp > 0 )
		{      
			ProcessCommand( ComRecBuff );
			SendCRLFPrompt();		
		}
      };
}                               
Пример #4
0
Файл: main.c Проект: kLabUM/IoT
void main(){

    CyGlobalIntEnable;

    // Start up initial mote processes
    SleepTimer_Start();
    isr_SleepTimer_StartEx(sleepTimerWake_INT);
    FS_Init();  // SD Card
    modem_set_api_feed(FEED_ID, API_KEY);
    modem_start();
    ultrasonic_start();
    solinst_start();
    ADC_SAR_1_Start();
    //modem_power_off();
    
    packet_ready = 0u; 
    take_reading = 1u;
    t_sample = 2u;                                  // Initialize Sample Period to 2 minutes
    trigger_sampler = 0u;                           // Initialize automated sampler to not take a sample    
    bottle_count = 0u;                              // Initialize bottle count to zero

    NeoRTC_Start(rtcCallBackReceived);              // Start and enable the RTC.   
    NeoRTC_Set_Repeating_Minute_Alarm(t_sample);    // Set 1-minute alarm
   
    
    //  Uncomment below to set RTC
    /*
    NeoRtcTimeStruct tm = {
      .second = 00,
      .minute = 54,
      .hour = 18,
      .day = 27,
      .weekday = 2,
      .month = 5,
      .year = 2014,
    } ;
    RTC_WriteTime(tm); //sets time
    */


    for(;;){
    
        RTC_Process_Tasks();
        
        // Loop continuously and take a reading  
        // every "t_sample" minutes.
        // The variable "take_reading" is set to TRUE 
        // by rtcCallBackReceived() defined after the for() loop
        if(take_reading){ 

            // Turn on the modem to update state variables:
            //  sampling frequency; triggering the autosampler
            modem_power_on();   
           
            if (clear_packet(data_packet)) {
                packet_ready = 0u;
            }
                        
            // To communicate with the IoT platform, the node 
            // 1) listens on a given port and 2) parses an incoming string 
            // for relevant commands. Once a packet is ready to send (3), 
            // the node 4) transmits the packet.  This is achieved in as little 
            // as four lines of code by leveraging an existing TCP/IP library.
            //
            // 1) modem_get_packet()
            // 2) packet_get_uint8()
            // 3) sprintf(data_packet, ...
            // 4) modem_send_packet()
            //
            if (modem_get_packet(data_packet,"t_sample,trigger_sampler")) {
                
                // Read in any updated values
                if(packet_get_uint8(data_packet, "t_sample", &tmp)){
                    t_sample = tmp;
                }
                if(packet_get_uint8(data_packet, "trigger_sampler", &tmp)){
                    trigger_sampler = tmp;
                }
            }

            /*
            if (send_attempts > 0) {
                debug_write("New reading taken before previous packet was sent");
            }
            */

            // Trigger the autosampler to collect the sample 
            // if a sample is requested
            if (trigger_sampler){
                
                // Send in acknowledgement that packet containing
                // info re:automated sampler has been received:
                modem_send_packet("trigger_sampler, 0");
                
                trigger_sampler = 0; // Update the value locally
                
                // Trigger the autosampler as long as there are still available samples
                // If bottle_count >= MAX_BOTTLE_COUNT, skip taking a sample and avoid
                // waiting for the code to timeout
                if (bottle_count < MAX_BOTTLE_COUNT) {
                    // Turn off modem to conserve energy
                    modem_power_off();
                    
                    // Start up the autosampler processes 
                    // and power on the autosampler
                    autosampler_start();
                    autosampler_power_on();
                    

                    // Trigger the autosampler and update current bottle_count
                    autosampler_take_sample(&bottle_count);
                    
                    // Power off the autosampler
                    // and shut down the autosampler processes 
                    autosampler_power_off(); 
                    autosampler_stop();    
                }
                else {
                    debug_write("bottle_count >= MAX_BOTTLE_COUNT");
                }
            }
            
            // Construct the data packet that will be transmitted
            // by the sensor node, starting with the bottle the
            // autosampler last collected a sample in
            // (the packet is in .csv format)
            sprintf(data_packet,"%s, %u\r\n",
                "bottle", bottle_count);

            // Get Sensor Readings for:
            //  Depth, Pressure, Temperature, Conductivity
            // and update the data packet                
            if (solinst_get_reading(&solinst_reading)){
                sprintf(data_packet,"%s%s, %f\r\n", data_packet,
                    "depth_press", solinst_reading.depth);            
                    
                sprintf(data_packet,"%s%s, %f\r\n", data_packet,
                    "temp_press", solinst_reading.temp);                      
            }
            
            if (ultrasonic_get_reading(&ultrasonic_reading)){
                sprintf(data_packet,"%s%s, %f\r\n", data_packet,
                    "depth_sonic", ultrasonic_reading.depth);              
            }
            if (ReadBatteryVoltage(&vBattery)){
                sprintf(data_packet,"%s%s, %f\r\n", data_packet,
                    "V_batt", vBattery);              
            }

            // An example of writing data in JSON format
            // This was replaced with .csv format due to 
            // .csv's smaller packet size
            /*
            sprintf(data_packet, "{"
                      "\"method\":\"put\","
                      "\"resource\":\"/feeds/%d\","
                      "\"headers\":{\"X-ApiKey\":\"%s\"},"
                      "\"body\":{\"version\":\"1.0.0\",\"datastreams\":["
                            "{ \"id\" : \"depth_sonic\", \"current_value\" : \"%f\"},"
                            "{ \"id\" : \"depth_press\", \"current_value\" : \"%f\"},"
                            "{ \"id\" : \"temp_press\", \"current_value\" : \"%f\"},"
                            "{ \"id\" : \"trigger_sampler\", \"current_value\" : \"%d\"},"
                            "{ \"id\" : \"V_batt\",  \"current_value\" : \"%f\"}"
                      "]}}",
                      FEED_ID,API_KEY,
                      ultrasonic_reading.depth, solinst_reading.depth, solinst_reading.temp,0u,vBattery);
            */

            // Update flags for sending a packet and taking sensor readings
            packet_ready = 1u;
            take_reading = 0u;
            //send_attempts = 0u;
        
        // Once the flag for packet_ready has been set, 
        // send the packet and save the packet locally
        } else if(packet_ready){
            isr_SleepTimer_Stop;  //  <============= ADDRESS THIS WITH B.K.
            
            // Power on the modem in case it was turned off
            modem_power_on();
            
            // modem_state should now be IDLE or READY
            // and we can send the packet
            modem_send_packet(data_packet);
            
            // Power off the modem and conserve energy
            modem_power_off();
            
            // Backup data to SD Card
            // Use the current time to time-stamp the current reading
            NeoRtcTimeStruct tm_neo = NeoRTC_Read_Time();

            // Overwrite current data_packet with time-stamped data
            sprintf(data_packet, "\r\n%d:%d:%d %d/%d/%d -- [ID %d] u_d=%f s_d=%f s_t=%f bottle=%d v_b=%f", tm_neo.hour, tm_neo.minute,
                             tm_neo.second, tm_neo.day, tm_neo.month, tm_neo.year, moteID,
                             ultrasonic_reading.depth, solinst_reading.depth, solinst_reading.temp,bottle_count,vBattery);
            
            // Write data_packet to a *.txt file on the SD Card
            Write_To_SD_Card("data.txt","a",data_packet,strlen(data_packet));            

            // Clear the current packet in preparation for the next reading
            // when the node awakens from sleep
            if (clear_packet(data_packet)) {
                packet_ready = 0u;
            }
        
        // If either the sensor node should take a reading nor send a packet
        // go to low power mode to increase battery life    
        }else{
            // Set repeating alarm to trigger every "t_sample" minutes
            NeoRTC_Set_Repeating_Minute_Alarm(t_sample);  
            Goto_Low_Power_Mode();
        }
    CyDelay(1u);  // Quick Pause to prevent locking
    }
}