/*
  return distance in centimeters
 */
float AP_RangeFinder_analog::distance_cm(void)
{
    if (!_enabled) {
        return 0.0f;
    }

    /* first convert to volts */
    float v = voltage();
    float dist_m = 0;

    switch ((AP_RangeFinder_analog::RangeFinder_Function)_function.get()) {
    case FUNCTION_LINEAR:
        dist_m = (v - _offset) * _scaling;
        break;

    case FUNCTION_INVERTED:
        dist_m = (_offset - v) * _scaling;
        break;

    case FUNCTION_HYPERBOLA:
        if (v <= _offset) {
            dist_m = 0;
        }
        dist_m = _scaling / (v - _offset);
        if (isinf(dist_m) || dist_m > _max_distance_cm) {
            dist_m = _max_distance_cm * 0.01;
        }
        break;
    }
    if (dist_m < 0) {
        dist_m = 0;
    }
    return dist_m * 100.0f;
}
void AP_BattMonitor::check_failsafes(void)
{
    if (hal.util->get_soft_armed()) {
        for (uint8_t i = 0; i < _num_instances; i++) {
            if (drivers[i] == nullptr) {
                continue;
            }

            const BatteryFailsafe type = drivers[i]->update_failsafes();
            if (type <= state[i].failsafe) {
                continue;
            }

            int8_t action = 0;
            const char *type_str = nullptr;
            switch (type) {
                case AP_BattMonitor::BatteryFailsafe_None:
                    continue; // should not have been called in this case
                case AP_BattMonitor::BatteryFailsafe_Low:
                    action = _params[i]._failsafe_low_action;
                    type_str = "low";
                    break;
                case AP_BattMonitor::BatteryFailsafe_Critical:
                    action = _params[i]._failsafe_critical_action;
                    type_str = "critical";
                    break;
            }

            gcs().send_text(MAV_SEVERITY_WARNING, "Battery %d is %s %.2fV used %.0f mAh", i + 1, type_str,
                            (double)voltage(i), (double)consumed_mah(i));
            _has_triggered_failsafe = true;
            AP_Notify::flags.failsafe_battery = true;
            state[i].failsafe = type;

            // map the desired failsafe action to a prioritiy level
            int8_t priority = 0;
            if (_failsafe_priorities != nullptr) {
                while (_failsafe_priorities[priority] != -1) {
                    if (_failsafe_priorities[priority] == action) {
                        break;
                    }
                    priority++;
                }

            }

            // trigger failsafe if the action was equal or higher priority
            // It's valid to retrigger the same action if a different battery provoked the event
            if (priority <= _highest_failsafe_priority) {
                _battery_failsafe_handler_fn(type_str, action);
                _highest_failsafe_priority = priority;
            }
        }
    }
}
Exemple #3
0
void main (void) {
	long command, left, right;
	int rec, i;
	P0_5=1;

	while (1) {
		printf("%ld\n", travelled);
		rec = 1;
		for (i = 0; i < 4; i++){
			if (voltage(0) > MIN){
				rec = 0;
			}
		}
		if (!rec){
			right = getDistance(2);
			left = getDistance(1);

			if (orientation == REVERSE){
				long temp = left;
				left = right;
				right = temp;
			}

			if (autonomous){
				if (left > right + 300){
					motorRight.power = 0;
					motorLeft.power = totalpower;
				} else if (right > left + 300){
					motorLeft.power = 0;
					motorRight.power = totalpower;
				} else if (left > distance * ERROR){
					motorLeft.direction = FORWARD;
					motorRight.direction = FORWARD;
					motorLeft.power = totalpower;
					motorRight.power = totalpower;
				} else if (left < distance / ERROR){
					motorLeft.direction = REVERSE;
					motorRight.direction = REVERSE;
					motorLeft.power = totalpower;
					motorRight.power = totalpower;
				} else {
					motorLeft.power = 0;
					motorRight.power = 0;
				}
			}
		} else {
			motorLeft.power = 0;
			motorRight.power = 0;
			waitms(10); //this makes sure that the power change takes effect before shutting off the interrupt
			command = rx_byte();
			implement_command(command);
			waitms(200); //prevents receiving commands back to back
		}
	}
} 
Exemple #4
0
unsigned char rx_byte ( float min )
{
	unsigned char j;
	unsigned char val = 0;
	float v;
	int c;

	wait_one_and_half_bit_time();
	
	for(j=0; j<8; j++) {
		v = voltage(0);
		if (j == 0) {
			volt_right = v;
			volt_left = voltage(1);
		}
		c = (v>min);
		P2_0 = c;
		val |= (c)?(0x01<<j):0x00;
		wait_bit_time();
	}
	return val;
}
Exemple #5
0
void
SurfaceCurrent::Update()
{
   delete pcg_;
   delete amg_;
   delete S0_;
   delete PSI_;
   delete RHS_;
   delete K_;

   psi_->Update();
   *psi_ = 0.0;

   s0_->Update();
   s0_->Assemble();
   s0_->Finalize();
   S0_ = s0_->ParallelAssemble();

   amg_ = new HypreBoomerAMG(*S0_);
   amg_->SetPrintLevel(0);

   pcg_ = new HyprePCG(*S0_);
   pcg_->SetTol(1e-12);
   pcg_->SetMaxIter(200);
   pcg_->SetPrintLevel(0);
   pcg_->SetPreconditioner(*amg_);

   // Apply piecewise constant voltage boundary condition
   Array<int> vbc_bdr_attr(H1FESpace_->GetParMesh()->bdr_attributes.Max());
   for (int i=0; i<vbcs_->Size(); i++)
   {
      ConstantCoefficient voltage((*vbcv_)[i]);
      vbc_bdr_attr = 0;
      vbc_bdr_attr[(*vbcs_)[i]-1] = 1;
      psi_->ProjectBdrCoefficient(voltage, vbc_bdr_attr);
   }

   PSI_ = psi_->ParallelProject();
   RHS_ = new HypreParVector(H1FESpace_);
   K_   = new HypreParVector(HCurlFESpace_);

   s0_->ParallelEliminateEssentialBC(ess_bdr_,
                                     *S0_,
                                     *PSI_, *RHS_);
}
int ButtonPin::readButtons() {

	float volts = voltage();

	// None pressed
	if( volts < .1 ) {
		BPIN_SELECT = 0;
		BPIN_UP     = 0;
 		BPIN_DOWN   = 0;
		BPIN_LEFT   = 0;
		BPIN_RIGHT  = 0;
		return 0;
	} 
	
	if( volts > 4 ) BPIN_SELECT = 1;
	else if( volts >  3 ) BPIN_UP = 1;
	else if( volts >  2 ) BPIN_DOWN = 1;
	else if( volts >  1 ) BPIN_LEFT = 1;
	else if( volts > .1 ) BPIN_RIGHT = 1;
		
	return 1;
}
Exemple #7
0
/**
 * Returns the current voltage as a string, this function ensures that
 * the voltage will always display two decimals, even if the number is
 * an integer (e.g. this function will return "12.00 V")
 */
QString DriverStation::voltageString() const
{
    /* Round voltage to two decimal places */
    qreal volt = roundf (voltage() * 100) / 100;

    /* Avoid this: http://i.imgur.com/iAAi1bX.png */
    if (volt > maximumBatteryVoltage())
        volt = maximumBatteryVoltage();

    /* Separate voltage into natural and decimal numbers */
    int integer = static_cast<int> (volt);
    int decimal = static_cast<qreal> (volt - integer) * 100;

    /* Convert the obtained numbers into strings */
    QString integer_str = QString::number (integer);
    QString decimal_str = QString::number (decimal);

    /* Prepend a 0 to the decimal numbers if required */
    if (decimal < 10)
        decimal_str.prepend ("0");

    /* Construct final string */
    return integer_str + "." + decimal_str + " V";
}
Exemple #8
0
		val |= (c)?(0x01<<j):0x00;
		wait_bit_time();
	}
	return val;
}

void pwmcounter (void) interrupt 1
{
	
	float f;
	volatile char b;
	struct QueueItem* item;
	
	EA = 0;

	f = voltage(0);
	//printf("%f %f", f, minimum_logic_voltage);
	
	if (f > minimum_logic_voltage) {
	
		P2_0 = 0;
		b = rx_byte((f*0.25));
		
		if (b != NOTHING_BYTE && b != DISTANCE_BYTE) {
			item = newItem(b);
			append(q, item);
			zeroCount = 0;
		} else if (b == NOTHING_BYTE) {
			zeroCount++;
		} else {
			zeroCount = 0;
Exemple #9
0
void
VoltaSolver::Solve()
{
   if (myid_ == 0) { cout << "Running solver ... " << endl << flush; }

   // Initialize the electric potential with its boundary conditions
   *phi_ = 0.0;

   if ( dbcs_->Size() > 0 )
   {
      if ( phiBCCoef_ )
      {
         // Apply gradient boundary condition
         phi_->ProjectBdrCoefficient(*phiBCCoef_, ess_bdr_);
      }
      else
      {
         // Apply piecewise constant boundary condition
         Array<int> dbc_bdr_attr(pmesh_->bdr_attributes.Max());
         for (int i=0; i<dbcs_->Size(); i++)
         {
            ConstantCoefficient voltage((*dbcv_)[i]);
            dbc_bdr_attr = 0;
            dbc_bdr_attr[(*dbcs_)[i]-1] = 1;
            phi_->ProjectBdrCoefficient(voltage, dbc_bdr_attr);
         }
      }
   }

   // Initialize the RHS vector
   HypreParVector *RHS = new HypreParVector(H1FESpace_);
   *RHS = 0.0;

   // Initialize the volumetric charge density
   if ( rho_ )
   {
      rho_->ProjectCoefficient(*rhoCoef_);

      HypreParMatrix *MassH1 = h1Mass_->ParallelAssemble();
      HypreParVector *Rho    = rho_->ParallelProject();

      MassH1->Mult(*Rho,*RHS);

      delete MassH1;
      delete Rho;
   }

   // Initialize the Polarization
   HypreParVector *P = NULL;
   if ( p_ )
   {
      p_->ProjectCoefficient(*pCoef_);
      P = p_->ParallelProject();

      HypreParMatrix *MassHCurl = hCurlMass_->ParallelAssemble();
      HypreParVector *PD        = new HypreParVector(HCurlFESpace_);

      MassHCurl->Mult(*P,*PD);
      Grad_->MultTranspose(*PD,*RHS,-1.0,1.0);

      delete MassHCurl;
      delete PD;

   }

   // Initialize the surface charge density
   if ( sigma_ )
   {
      *sigma_ = 0.0;

      Array<int> nbc_bdr_attr(pmesh_->bdr_attributes.Max());
      for (int i=0; i<nbcs_->Size(); i++)
      {
         ConstantCoefficient sigma_coef((*nbcv_)[i]);
         nbc_bdr_attr = 0;
         nbc_bdr_attr[(*nbcs_)[i]-1] = 1;
         sigma_->ProjectBdrCoefficient(sigma_coef, nbc_bdr_attr);
      }

      HypreParMatrix *MassS = h1SurfMass_->ParallelAssemble();
      HypreParVector *Sigma = sigma_->ParallelProject();

      MassS->Mult(*Sigma,*RHS,1.0,1.0);

      delete MassS;
      delete Sigma;
   }

   // Apply Dirichlet BCs to matrix and right hand side
   HypreParMatrix *DivEpsGrad = divEpsGrad_->ParallelAssemble();
   HypreParVector *Phi        = phi_->ParallelProject();

   // Apply the boundary conditions to the assembled matrix and vectors
   if ( dbcs_->Size() > 0 )
   {
      // According to the selected surfaces
      divEpsGrad_->ParallelEliminateEssentialBC(ess_bdr_,
                                                *DivEpsGrad,
                                                *Phi, *RHS);
   }
   else
   {
      // No surfaces were labeled as Dirichlet so eliminate one DoF
      Array<int> dof_list(0);
      if ( myid_ == 0 )
      {
         dof_list.SetSize(1);
         dof_list[0] = 0;
      }
      DivEpsGrad->EliminateRowsCols(dof_list, *Phi, *RHS);
   }

   // Define and apply a parallel PCG solver for AX=B with the AMG
   // preconditioner from hypre.
   HypreSolver *amg = new HypreBoomerAMG(*DivEpsGrad);
   HyprePCG *pcg = new HyprePCG(*DivEpsGrad);
   pcg->SetTol(1e-12);
   pcg->SetMaxIter(500);
   pcg->SetPrintLevel(2);
   pcg->SetPreconditioner(*amg);
   pcg->Mult(*RHS, *Phi);

   delete amg;
   delete pcg;
   delete DivEpsGrad;
   delete RHS;

   // Extract the parallel grid function corresponding to the finite
   // element approximation Phi. This is the local solution on each
   // processor.
   *phi_ = *Phi;

   // Compute the negative Gradient of the solution vector.  This is
   // the magnetic field corresponding to the scalar potential
   // represented by phi.
   HypreParVector *E = new HypreParVector(HCurlFESpace_);
   Grad_->Mult(*Phi,*E,-1.0);
   *e_ = *E;

   delete Phi;

   // Compute electric displacement (D) from E and P
   if (myid_ == 0) { cout << "Computing D ... " << flush; }

   HypreParMatrix *HCurlHDivEps = hCurlHDivEps_->ParallelAssemble();
   HypreParVector *ED = new HypreParVector(HDivFESpace_);
   HypreParVector *D  = new HypreParVector(HDivFESpace_);

   HCurlHDivEps->Mult(*E,*ED);

   if ( P )
   {
      HypreParMatrix *HCurlHDiv = hCurlHDiv_->ParallelAssemble();
      HCurlHDiv->Mult(*P,*ED,-1.0,1.0);
      delete HCurlHDiv;
   }

   HypreParMatrix * MassHDiv = hDivMass_->ParallelAssemble();

   HyprePCG * pcgM = new HyprePCG(*MassHDiv);
   pcgM->SetTol(1e-12);
   pcgM->SetMaxIter(500);
   pcgM->SetPrintLevel(0);
   HypreDiagScale *diagM = new HypreDiagScale;
   pcgM->SetPreconditioner(*diagM);
   pcgM->Mult(*ED,*D);

   *d_ = *D;

   if (myid_ == 0) { cout << "done." << flush; }

   delete diagM;
   delete pcgM;
   delete HCurlHDivEps;
   delete MassHDiv;
   delete E;
   delete ED;
   delete D;
   delete P;

   if (myid_ == 0) { cout << " Solver done. " << flush; }
}
Exemple #10
0
SurfaceCurrent::SurfaceCurrent(ParFiniteElementSpace & H1FESpace,
                               ParFiniteElementSpace & HCurlFESpace,
                               ParDiscreteGradOperator & Grad,
                               Array<int> & kbcs,
                               Array<int> & vbcs, Vector & vbcv)
   : H1FESpace_(&H1FESpace),
     HCurlFESpace_(&HCurlFESpace),
     Grad_(&Grad),
     kbcs_(&kbcs),
     vbcs_(&vbcs),
     vbcv_(&vbcv)
{
   // Initialize MPI variables
   MPI_Comm_rank(H1FESpace_->GetParMesh()->GetComm(), &myid_);

   s0_ = new ParBilinearForm(H1FESpace_);
   s0_->AddBoundaryIntegrator(new DiffusionIntegrator);
   s0_->Assemble();
   s0_->Finalize();
   S0_ = s0_->ParallelAssemble();

   amg_ = new HypreBoomerAMG(*S0_);
   amg_->SetPrintLevel(0);

   pcg_ = new HyprePCG(*S0_);
   pcg_->SetTol(1e-12);
   pcg_->SetMaxIter(200);
   pcg_->SetPrintLevel(0);
   pcg_->SetPreconditioner(*amg_);

   ess_bdr_.SetSize(H1FESpace_->GetParMesh()->bdr_attributes.Max());
   ess_bdr_ = 0;
   for (int i=0; i<vbcs_->Size(); i++)
   {
      ess_bdr_[(*vbcs_)[i]-1] = 1;
   }

   non_k_bdr_.SetSize(H1FESpace_->GetParMesh()->bdr_attributes.Max());
   non_k_bdr_ = 1;
   for (int i=0; i<kbcs_->Size(); i++)
   {
      non_k_bdr_[(*kbcs_)[i]-1] = 0;
   }

   psi_ = new ParGridFunction(H1FESpace_);
   *psi_ = 0.0;

   // Apply piecewise constant voltage boundary condition
   Array<int> vbc_bdr_attr(H1FESpace_->GetParMesh()->bdr_attributes.Max());
   for (int i=0; i<vbcs_->Size(); i++)
   {
      ConstantCoefficient voltage((*vbcv_)[i]);
      vbc_bdr_attr = 0;
      vbc_bdr_attr[(*vbcs_)[i]-1] = 1;
      psi_->ProjectBdrCoefficient(voltage, vbc_bdr_attr);
   }

   PSI_ = psi_->ParallelProject();
   RHS_ = new HypreParVector(H1FESpace_);
   K_   = new HypreParVector(HCurlFESpace_);

   s0_->ParallelEliminateEssentialBC(ess_bdr_,
                                     *S0_,
                                     *PSI_, *RHS_);
}
    void TestMonodomain3d() throw(Exception)
    {
        /* HOW_TO_TAG Cardiac/Problem definition
         * Generate a slab (cuboid) mesh rather than read a mesh in, and pass it to solver
         */

        /* We will auto-generate a mesh this time, and pass it in, rather than
         * provide a mesh file name. This is how to generate a cuboid mesh with
         * a given spatial stepsize h */
        TetrahedralMesh<3,3> mesh;
        double h=0.02;
        mesh.ConstructRegularSlabMesh(h, 0.8 /*length*/, 0.3 /*width*/, 0.3 /*depth*/);
        /* (In 2D the call is identical, but without the depth parameter).
         *
         * EMPTYLINE
         *
         * Set the simulation duration, etc, and create an instance of the cell factory.
         * One thing that should be noted for monodomain problems, the ''intracellular
         * conductivity'' is used as the monodomain effective conductivity (not a
         * harmonic mean of intra and extracellular conductivities). So if you want to
         * alter the monodomain conductivity call
         * `HeartConfig::Instance()->SetIntracellularConductivities`
         */
        HeartConfig::Instance()->SetSimulationDuration(5); //ms
        HeartConfig::Instance()->SetOutputDirectory("Monodomain3dExample");
        HeartConfig::Instance()->SetOutputFilenamePrefix("results");
        HeartConfig::Instance()->SetOdePdeAndPrintingTimeSteps(0.005, 0.01, 0.1);

        BenchmarkCellFactory cell_factory;

        /* Now we declare the problem class, `MonodomainProblem<3>` instead of `BidomainProblem<2>`.
         * The interface for both is the same.
         */
        MonodomainProblem<3> monodomain_problem( &cell_factory );

        /* If a mesh-file-name hasn't been set using `HeartConfig`, we have to pass in
         * a mesh using the `SetMesh` method (must be called before `Initialise`). */
        monodomain_problem.SetMesh(&mesh);

        /* By default data for all nodes is output, but for big simulations, sometimes this
         * might not be required, and the action potential only at certain nodes required.
         * The following code shows how to output the results at the first, middle and last
         * nodes, for example. (The output is written to the HDF5 file; regular visualisation output
         * will be turned off. HDF5 files can be read using Matlab). We are not using this in this
         * simulation however (hence the boolean being set to false).
         */
        bool partial_output = false;
        if(partial_output)
        {
            std::vector<unsigned> nodes_to_be_output;
            nodes_to_be_output.push_back(0);
            nodes_to_be_output.push_back((unsigned)round( (mesh.GetNumNodes()-1)/2 ));
            nodes_to_be_output.push_back(mesh.GetNumNodes()-1);
            monodomain_problem.SetOutputNodes(nodes_to_be_output);
        }

        /* `SetWriteInfo` is a useful method that means that the min/max voltage is
         * printed as the simulation runs (useful for verifying that cells are stimulated
         * and the wave propagating, for example) (although note scons does buffer output
         * before printing to screen) */
        monodomain_problem.SetWriteInfo();

        /* Finally, call `Initialise` and `Solve` as before */
        monodomain_problem.Initialise();
        monodomain_problem.Solve();

        /* This part is just to check nothing has accidentally been changed in this example */
        ReplicatableVector voltage(monodomain_problem.GetSolution());
        TS_ASSERT_DELTA(voltage[0], 34.9032, 1e-2);
    }
int main(int argc, char *argv[])
#endif
{
#if !defined(SINGLE_PHASE)
    int ch;
    static struct phase_parms_s *phase;
    static struct phase_nv_parms_s const *phase_nv;
#endif
    static int32_t x;
    int i;

#if !defined(__MSP430__)
    if (start_host_environment(argc, argv) < 0)
        exit(2);
#endif
    system_setup();

#if !defined(ESP_SUPPORT)  &&  defined(PHASE_CORRECTION_SUPPORT)  &&  !defined(DYNAMIC_PHASE_CORRECTION_SUPPORT)
    #if !defined(SINGLE_PHASE)
    for (ch = 0;  ch < NUM_PHASES;  ch++)
    {
        phase = &chan[ch];
        phase_nv = &nv_parms.seg_a.s.chan[ch];
    #endif
    #if defined(__MSP430_HAS_ADC12__)  ||  defined(__MSP430_HAS_ADC10__)
        set_phase_correction(&phase->metrology.current.in_phase_correction[0], phase_nv->current.phase_correction[0]);
        #if GAIN_STAGES > 1
        set_phase_correction(&phase->metrology.current.in_phase_correction[1], phase_nv->current.phase_correction[1]);
        #endif
        #if defined(SINGLE_PHASE)  &&  defined(NEUTRAL_MONITOR_SUPPORT)
        set_phase_correction(&phase->neutral.in_phase_correction[0], nv_parms.seg_a.s.neutral.phase_correction[0]);
            #if GAIN_STAGES > 1
        set_phase_correction(&phase->neutral.in_phase_correction[1], nv_parms.seg_a.s.neutral.phase_correction[1]);
            #endif
        #endif
    #else
        #if defined(SINGLE_PHASE)
        set_sd16_phase_correction(&phase->metrology.current.in_phase_correction[0], 0, phase_nv->current.phase_correction[0]);
            #if defined(NEUTRAL_MONITOR_SUPPORT)
        set_sd16_phase_correction(&phase->metrology.neutral.in_phase_correction[0], 1, nv_parms.seg_a.s.neutral.phase_correction[0]);
            #endif
        #else
        set_sd16_phase_correction(&phase->metrology.current.in_phase_correction[0], ch, phase_nv->current.phase_correction[0]);
        #endif
    #endif
    #if !defined(SINGLE_PHASE)
    }
    #endif
#endif

#if defined(ESP_SUPPORT)
    esp_init();
    esp_start_measurement();
#endif

#if defined(MULTI_RATE_SUPPORT)
    tariff_initialise();
#endif
    send_message(0, 1);

    for (;;)
    {
        kick_watchdog();
#if !defined(__MSP430__)
        /* In the host environment we need to simulate interrupts here */
        adc_interrupt();
#endif
#if !defined(SINGLE_PHASE)
        phase = chan;
        phase_nv = nv_parms.seg_a.s.chan;

        for (ch = 0;  ch < NUM_PHASES;  ch++)
        {
#endif
            /* Unless we are in normal operating mode, we should wait to be
               woken by a significant event from the interrupt routines. */
////#if  1 //// 0 //defined(__MSP430__)
////            if (operating_mode != OPERATING_MODE_NORMAL)
#ifdef USE_LPM
                _BIS_SR(LPM0_bits);
#endif
#if defined(POWER_DOWN_SUPPORT)
            if (operating_mode == OPERATING_MODE_POWERFAIL)
                switch_to_powerfail_mode();
#endif
#if defined(LIMP_MODE_SUPPORT)  &&  defined(IEC1107_SUPPORT)
            if (nv_parms.seg_a.s.meter_uncalibrated)
                enable_ir_receiver();
#endif
            if ((phase->status & NEW_LOG))
            {
                /* The background activity has informed us that it is time to
                   perform a block processing operation. */
                phase->status &= ~NEW_LOG;
#if defined(MAGNETIC_INTERFERENCE_SUPPORT)
                if ((meter_status & STATUS_HIGH_MAGNETIC_FIELD))
                {
                    /* The meter is suffering magnetic tampering, so continuously
                       charge for a great deal of electricity. */
                    x = phase->readings.V_rms*MAGNETIC_INTERFERENCE_CURRENT/(10*100);
                }
                else
#endif
             
          
          
  //MM Added for LCD Fix; Start     
         
    
    
     #if defined(IHD430_SUPPORT)
         
               RF_Tx[12]=total_active_power_array.uint8[0];
               RF_Tx[13]=total_active_power_array.uint8[1];
               RF_Tx[14]=total_active_power_array.uint8[2];
               RF_Tx[15]=total_active_power_array.uint8[3]; 
               RF_Tx[16] =0x28 ^ RF_Tx[12] ^ RF_Tx[13] ^ RF_Tx[14] ^ RF_Tx[15];
               for (i=0; i<17; i++)
               {
                  UCA2TXBUF=RF_Tx[i];
                  while(!(UCA2IFG&UCTXIFG));
               }               
         #endif
    lcd_display_mode++;
     switch( lcd_display_mode ) 
              {
                  case DISPLAY_VOLTAGE:
                      change_display=1;
                      temp= phase->readings.V_rms;
                       if (temp <0) temp=0;
                       LCDM1=0xC;
                       LCDM2=0x29;
                      break;
                  case DISPLAY_CURRENT:
                       change_display=1;
                       temp= phase->readings.I_rms;
                       if (temp <0) temp=0;
                       LCDM1=0x9C;
                       LCDM2=0x1;
                       //MM Take care of different decimal.
                      break;
                  case DISPLAY_ACTIVE_POWER:
                     change_display=1;
                      temp= phase->readings.active_power;
                      if (temp <0) temp=0;
                      LCDM1=0xCF;
                       LCDM2=0x1;
                      break;
                  case DISPLAY_REACTIVE_POWER:
                      change_display=1;
                       temp= phase->readings.reactive_power;
                       if (temp <0) temp=0;
                       LCDM1=0xC7;
                       LCDM2=0x3;
                      break;
                  case DISPLAY_APPARENT_POWER:
                      change_display=1;
                       temp= phase->readings.apparent_power;
                       if (temp <0) temp=0;
                       LCDM1=0xB7;
                       LCDM2=0x1;
                      break;
                  case DISPLAY_FREQUENCY:
                      change_display=1;
                       temp= phase->readings.frequency;
                       if (temp <0) temp=0;
                       LCDM1=0x8F;
                       LCDM2=0x1;
                      break;  
                  case DISPLAY_POWER_FACTOR:
                      change_display=1;
                       temp= phase->readings.power_factor/10;
                       LCDM1=0x8F;
                       LCDM2=0x50;
                       if (temp < 0)
                       {
                          temp*= -1;
                         LCDM3=0x1C;
                       }
                       else
                       {
                          LCDM3= 0x9C; 
                       }
                       LCDM3constant=1;
                       //Take negative and positive case for inductive and capacitive
                      break;                  
                 case    DISPLAY_ACCUMULATED_POWER_TOTAL: 
                      change_display=1;
                      temp= phase->consumed_active_energy/10;
                      LCDM1=0x9F;
                       LCDM2=0x1;
                      break; 
              default:
                change_display=0;
                break;
                
                                     
            }
     //temp=12345;
         //total_active_power=0x12345;
// MM    Comment back in to display active power
//            if (total_active_power <0)
//            temp=-(total_active_power);
//          else
//            temp=total_active_power;
    
//MM Comment in two lines below  for counter test         //temp=12345;
//          temp2++;
//          temp=temp2;
         
            if(change_display)
            {
//               LCDM1 = 0;
//          LCDM2 = 0;          
          
             if(!LCDM3constant)
             {
               LCDM3 = 0;             
             }
             else
             {
               LCDM3constant=0;
             }
               
          LCDM4 = 0;
          LCDM5 = 0;
          LCDM6 = 0;
          LCDM7 = 0;
          LCDM8 = 0;
          LCDM9 = 0;
          LCDM10 = 0;
          LCDM11 = 0;
          LCDM12 = 0;          
          LCDM13 = 0;
          LCDM14 = 0;
          LCDM15 = 0;
          LCDM16 = 0;
          LCDM17 = 0;
          LCDM18 = 0;
          LCDM19 = 0;
          LCDM20 = 0;
          
         
       thou_thou=0;
         hun_thou=0;       
        ten_thou=0;
    thou=0;
    hun=0;
    ten=0;
    unit=0; 
                while (temp >=1000000)
                {
                    thou_thou++;
                    temp-=1000000;
                }
                 while (temp >=100000)
                {
                    hun_thou++;
                    temp-=100000;
                }
                while (temp >=10000)
                {
                    ten_thou++;
                    temp-=10000;
                }
                while (temp >=1000)
                {
                    thou++;
                    temp-=1000;
                }
                while (temp >=100)
                {
                    hun++;
                    temp-=100;
                }
                while (temp >=10)
                {
                    ten++;
                    temp-=10;
                }
                while (temp >=1)
                {
                    unit++;
                    temp--;
                }
               
                //MM: LCD fix to display higher active power readings
                if(thou_thou)
                {
                  LCDM11 = LCD_Char_Map[hun];
                  LCDM9 = LCD_Char_Map[thou];
                  //LCDM8 = 0x1;
                  LCDM7 = LCD_Char_Map[ten_thou];
                  LCDM5 = LCD_Char_Map[hun_thou];
                  LCDM3 = LCD_Char_Map[thou_thou];          
                }
                else if(hun_thou)
                {        
                  
                  LCDM11 = LCD_Char_Map[ten];
                  if (lcd_display_mode==DISPLAY_CURRENT) LCDM8 = 0x1;      
                  else if(lcd_display_mode!=DISPLAY_ACCUMULATED_POWER_TOTAL) LCDM10 = 0x1; //MM do nothing    
                  LCDM9 = LCD_Char_Map[hun];
                  LCDM7 = LCD_Char_Map[thou];
                  LCDM5 = LCD_Char_Map[ten_thou];
                  LCDM3 = LCD_Char_Map[hun_thou]; 
                }
                else
                {
                  LCDM11 = LCD_Char_Map[unit];
                  LCDM9 = LCD_Char_Map[ten];
                  if (lcd_display_mode==DISPLAY_CURRENT || lcd_display_mode==DISPLAY_POWER_FACTOR) 
                  {
                    LCDM6 = 0x1;
                  }
                  else if(lcd_display_mode==DISPLAY_ACCUMULATED_POWER_TOTAL) 
                  {
                    
                    LCDM10 = 0x1;
                      
                  }
                  else
                  {
                                       LCDM8 = 0x1; 
                  }
                     
                  if (lcd_display_mode!=DISPLAY_POWER_FACTOR) 
                     {
                       
                       LCDM3 = LCD_Char_Map[ten_thou];
 
                     }

                  LCDM7 = LCD_Char_Map[hun];
                  LCDM5 = LCD_Char_Map[thou];
                 
                }
                if (lcd_display_mode==DISPLAY_ACCUMULATED_POWER_TOTAL)
                {
                    lcd_display_mode=-2; 
                }
               
            }  
            
          //MM end        
                  
                if (operating_mode == OPERATING_MODE_NORMAL)
                {
                    /* We can only do real power assessment in full operating mode */
#if !defined(SINGLE_PHASE)
                    x = active_power(phase, phase_nv);
    #if defined(PRECALCULATED_PARAMETER_SUPPORT)
        #if defined(IRMS_SUPPORT)
                    phase->readings.I_rms = current(phase, phase_nv, ch);
        #endif
        #if defined(VRMS_SUPPORT)
                    phase->readings.V_rms = voltage(phase, phase_nv);
        #endif
    #endif
#else
                    x = active_power();
                    
    #if defined(PRECALCULATED_PARAMETER_SUPPORT)
        #if defined(IRMS_SUPPORT)
                    phase->readings.I_rms = current();
        #endif
        #if defined(VRMS_SUPPORT)
                    phase->readings.V_rms = voltage();
        #endif
    #endif
#endif
                }
#if defined(LIMP_MODE_SUPPORT)
                else if (operating_mode == OPERATING_MODE_LIMP)
                {
                    /* In limp mode we must assess estimated power from only the measured current. */
                    /* We cannot properly determine current reversal in this mode. Also, current
                       imbalance is really just a measure of which lead is still connected.
                       Just treat both the imbalance and reversal conditions as OK */
    #if !defined(SINGLE_PHASE)
                    x = current(phase, phase_nv, ch);
        #if defined(PRECALCULATED_PARAMETER_SUPPORT)  &&  defined(VRMS_SUPPORT)
                    phase->readings.V_rms = voltage(phase, phase_nv);
        #endif
    #else
                    x = current();
        #if defined(PRECALCULATED_PARAMETER_SUPPORT)  &&  defined(VRMS_SUPPORT)
                    phase->readings.V_rms = voltage();
        #endif
    #endif
    #if defined(PRECALCULATED_PARAMETER_SUPPORT)  &&  defined(IRMS_SUPPORT)
                    phase->readings.I_rms = x;
    #endif
                    x = x*MAINS_NOMINAL_VOLTAGE/10;
                }
#endif
                if (labs(x) < RESIDUAL_POWER_CUTOFF  ||  (phase->status & V_OVERRANGE))
                {
                    x = 0;
#if defined(PRECALCULATED_PARAMETER_SUPPORT)  &&  defined(IRMS_SUPPORT)
                    /* Avoid displaying a residual current, which is nothing more
                       than integrated noise. */
                    //phase->I_rms = 0;
#endif
                    /* Turn off the LEDs, regardless of the internal state of the
                       reverse and imbalance assessments. */
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)
                    meter_status &= ~STATUS_REVERSED;
                    clr_reverse_current_indicator();
#endif
#if defined(POWER_BALANCE_DETECTION_SUPPORT)
                    meter_status &= ~STATUS_EARTHED;
                    clr_earthed_indicator();
#endif
                }
                else
                {
                    if (operating_mode == OPERATING_MODE_NORMAL)
                    {
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)  &&  defined(PHASE_REVERSED_IS_TAMPERING)
                        if ((phase->status & PHASE_REVERSED))
                        {
                            meter_status |= STATUS_REVERSED;
                            set_reverse_current_indicator();
                        }
                        else
                        {
                            meter_status &= ~STATUS_REVERSED;
                            clr_reverse_current_indicator();
                        }
#endif
#if defined(POWER_BALANCE_DETECTION_SUPPORT)
                        if ((phase->status & PHASE_UNBALANCED))
                        {
                            meter_status |= STATUS_EARTHED;
                            set_earthed_indicator();
                        }
                        else
                        {
                            meter_status &= ~STATUS_EARTHED;
                            clr_earthed_indicator();
                        }
#endif
                    }
#if defined(LIMP_MODE_SUPPORT)
                    else
                    {
    #if defined(PHASE_REVERSED_DETECTION_SUPPORT)
                        /* We cannot tell forward from reverse current in limp mode,
                           so just say it is not reversed. */
                        meter_status &= ~STATUS_REVERSED;
                        clr_reverse_current_indicator();
    #endif
    #if defined(POWER_BALANCE_DETECTION_SUPPORT)
                        /* We are definitely in the unbalanced state, but only set
                           the indicator if we have persistence checked, and the current
                           is sufficient to sustain operation. */
                        if ((phase->status & PHASE_UNBALANCED)  &&  phase->readings.I_rms >= LIMP_MODE_MINIMUM_CURRENT)
                        {
                            meter_status |= STATUS_EARTHED;
                            set_earthed_indicator();
                        }
                        else
                        {
                            meter_status &= ~STATUS_EARTHED;
                            clr_earthed_indicator();
                        }
    #endif
                        /* Only run the IR interface if we are sure there is enough power from the
                           supply to support the additional current drain. If we have not yet been
                           calibrated we had better keep the IR port running so we can complete the
                           calibration. */
#if defined(LIMP_MODE_SUPPORT)  &&  defined(IEC1107_SUPPORT)
                        if (phase->I_rms >= LIMP_MODE_MINIMUM_CURRENT_FOR_IR
                            ||
                            nv_parms.seg_a.s.meter_uncalibrated)
                        {
                            enable_ir_receiver();
                        }
                        else
                        {
                            disable_ir_receiver();
                        }
#endif
                    }
#endif
                }
                //x /= 10;
#if defined(SINGLE_PHASE)  &&  defined(TOTAL_ACTIVE_ENERGY_SUPPORT)
                total_active_power = x;
#else
                total_active_power += (x - phase->readings.active_power);
#endif
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)  &&  defined(PHASE_REVERSED_IS_GENERATION)
#endif
               #if defined(IHD430_SUPPORT)
                total_active_power_array.uint32=total_active_power;

                #endif
                phase->readings.active_power = x;
#if defined(PRECALCULATED_PARAMETER_SUPPORT)
    #if defined(REACTIVE_POWER_SUPPORT)
        #if defined(SINGLE_PHASE)
                x = reactive_power();
        #else
                x = reactive_power(phase, phase_nv);
        #endif
        #if defined(SINGLE_PHASE)  &&  defined(TOTAL_REACTIVE_ENERGY_SUPPORT)
                total_reactive_power = x;
        #else
                total_reactive_power += (x - phase->readings.reactive_power);
        #endif
                phase->readings.reactive_power = x;
    #endif
    #if defined(APPARENT_POWER_SUPPORT)
        #if defined(SINGLE_PHASE)
                phase->readings.apparent_power = apparent_power();
        #else
                phase->readings.apparent_power = apparent_power(phase, phase_nv);
        #endif
    #endif
    #if defined(POWER_FACTOR_SUPPORT)
                /* The power factor should be calculated last */
        #if defined(SINGLE_PHASE)
                phase->readings.power_factor = power_factor();
        #else
                phase->readings.power_factor = power_factor(phase, phase_nv);
        #endif
    #endif
#endif
#if defined(PER_PHASE_ACTIVE_ENERGY_SUPPORT)
//                phase->active_energy_counter += x*phase->metrology.dot_prod_logged.sample_count;
//                while (phase->active_energy_counter > ENERGY_WATT_HOUR_THRESHOLD)
//                {
//                    phase->active_energy_counter -= ENERGY_WATT_HOUR_THRESHOLD;
//                    phase->consumed_active_energy++;
//                }
#endif
#if defined(PRECALCULATED_PARAMETER_SUPPORT)  && defined(MAINS_FREQUENCY_SUPPORT)
    #if defined(SINGLE_PHASE)
                phase->readings.frequency = frequency();
    #else
                phase->readings.frequency = frequency(phase, phase_nv);
    #endif
#endif
#if defined(MAGNETIC_INTERFERENCE_SUPPORT)
    #if !defined(SINGLE_PHASE)
                if (ch == 0)
    #endif
                {
                    if ((meter_status & STATUS_HIGH_MAGNETIC_FIELD))
                    {
                        if (phase->sample_count_logged/magnetic_sensor_count_logged < MAGNETIC_INTERFERENCE_SAMPLE_RATIO)
                        {
                            if (--magnetic_interference_persistence <= -MAGNETIC_INTERFERENCE_PERSISTENCE_CHECK)
                            {
                                meter_status &= ~STATUS_HIGH_MAGNETIC_FIELD;
                                magnetic_interference_persistence = 0;
                            }
                        }
                        else
                        {
                            magnetic_interference_persistence = 0;
                        }
                    }
                    else
                    {
                        if (phase->sample_count_logged/magnetic_sensor_count_logged >= MAGNETIC_INTERFERENCE_SAMPLE_RATIO)
                        {
                            if (++magnetic_interference_persistence >= MAGNETIC_INTERFERENCE_PERSISTENCE_CHECK)
                            {
                                meter_status |= STATUS_HIGH_MAGNETIC_FIELD;
                                magnetic_interference_persistence = 0;
                            }
                        }
                        else
                        {
                            magnetic_interference_persistence = 0;
                        }
                    }
                }
#endif
            }
#if defined(LIMP_MODE_SUPPORT)
            /* The voltage channel DC estimate will never move very much when the
               meter is operating normally. If it does move, there must be some
               tampering, such as a diode between the grid and the meter. */
            if (operating_mode == OPERATING_MODE_NORMAL)
            {
                if (phase->readings.V_rms < LIMP_MODE_VOLTAGE_THRESHOLD*100
                    ||
                    phase->metrology.V_dc_estimate[0] > UPPER_TAMPER_V_DC_ESTIMATE
                    ||
                    phase->metrology.V_dc_estimate[0] < LOWER_TAMPER_V_DC_ESTIMATE)
                {
                    switch_to_limp_mode();
                }
            }
            else if (operating_mode == OPERATING_MODE_LIMP)
            {
                if (phase->readings.V_rms >= NORMAL_MODE_VOLTAGE_THRESHOLD*100
                    &&
                    phase->metrology.V_dc_estimate[1] <= UPPER_LIMP_TAMPER_V_DC_ESTIMATE
                    &&
                    phase->metrology.V_dc_estimate[1] >= LOWER_LIMP_TAMPER_V_DC_ESTIMATE)
                {
                    /* The LCD might need to be revived */
    #if defined(__MSP430__)
                    LCDawaken();
    #else
                    /* Tell the world we are ready to start */
    #endif
                    switch_to_normal_mode();
                }
            }
#endif

#if !defined(SINGLE_PHASE)
            phase++;
            phase_nv++;
        }
#endif
#if !defined(SINGLE_PHASE)  &&  defined(NEUTRAL_MONITOR_SUPPORT)  &&  defined(IRMS_SUPPORT)
        if ((neutral.status & NEW_LOG))
        {
            /* The background activity has informed us that it is time to
               perform a block processing operation. */
            neutral.status &= ~NEW_LOG;
            neutral.readings.I_rms = neutral_current();
        }
#endif

#if defined(MULTI_RATE_SUPPORT)
        tariff_management();
#endif

        /* Do display and other housekeeping here */
        if ((meter_status & TICKER))
        {
            /* Two seconds have passed */
            /* We have a 2 second tick */
            meter_status &= ~TICKER;
#if defined(__MSP430__)  &&  defined(BASIC_LCD_SUPPORT)
            /* Update the display, cycling through the phases */
            update_display();
#endif
            custom_2second_handler();
#if (defined(RTC_SUPPORT)  ||  defined(CUSTOM_RTC_SUPPORT))  &&  defined(CORRECTED_RTC_SUPPORT)
            correct_rtc();
#endif
        }
        custom_keypad_handler();
        custom_mainloop_handler();
#if defined(MESH_NET_SUPPORT)
        if (rf_service)
        {
            rf_service = 0;
            rf_tick_service();
        }
#endif
    }
#if !defined(__AQCOMPILER__)  &&  !defined(__IAR_SYSTEMS_ICC__)
    return  0;
#endif
}
int32_t current_rms_voltage(int ph)
{
    return voltage(&chan[ph], &nv_parms.seg_a.s.chan[ch]);
}
Exemple #14
0
/*
 * Parse the incoming data for valid messages
 */
void ControlBoard::parseSerialData(void)
{
  if (serialData.size() < CB_BUFFER_SIZE) {
	// Not enough data
	return;
  }

  // Check for a full message ending to \n
  if (serialData.endsWith('\n')) {

	// Remove \r\n
    int chop = 1;
    if (serialData.endsWith("\r\n")) {
      chop++;
    }

    serialData.chop(chop);

	qDebug() << __FUNCTION__ << "have msg:" << serialData.data();
  } else {
	// Wait for more data
	return;
  }

  // Parse temperature
  if (serialData.startsWith("tmp: ")) {
	serialData.remove(0,5);

	quint16 value = serialData.trimmed().toInt();

	qDebug() << __FUNCTION__ << "Temperature:" << value;
	emit(temperature(value));
  } else if (serialData.startsWith("dst: ")) {
	serialData.remove(0,5);

	quint16 value = serialData.trimmed().toInt();

	qDebug() << __FUNCTION__ << "Distance:" << value;
	emit(distance(value));
  } else if (serialData.startsWith("amp: ")) {
	serialData.remove(0,5);

	quint16 value = serialData.trimmed().toInt();

	qDebug() << __FUNCTION__ << "Current consumption:" << value;
	emit(current(value));
  } else if (serialData.startsWith("vlt: ")) {
	serialData.remove(0,5);

	quint16 value = serialData.trimmed().toInt();

	qDebug() << __FUNCTION__ << "Battery voltage:" << value;
	emit(voltage(value));
  } else if (serialData.startsWith("d: ")) {
	serialData.remove(0,3);

	QString *debugmsg = new QString(serialData);

	emit(debug(debugmsg));
  }
  serialData.clear();
}
    void Test2dBathMultipleBathConductivities() throw (Exception)
    {
        HeartConfig::Instance()->SetSimulationDuration(2.0);  //ms
        HeartConfig::Instance()->SetOutputDirectory("BidomainBath2dMultipleBathConductivities");
        HeartConfig::Instance()->SetOutputFilenamePrefix("bidomain_bath_2d");

        HeartConfig::Instance()->SetOdeTimeStep(0.001);  //ms ???

        std::set<unsigned> tissue_ids;
        tissue_ids.insert(0); // Same as default value defined in HeartConfig

        std::set<unsigned> bath_ids;
        bath_ids.insert(2);
        bath_ids.insert(3);
        bath_ids.insert(4);
        HeartConfig::Instance()->SetTissueAndBathIdentifiers(tissue_ids, bath_ids);

        // need to create a cell factory but don't want any intra stim, so magnitude
        // of stim is zero.
        c_vector<double,2> centre;
        centre(0) = 0.05; // cm
        centre(1) = 0.05; // cm
        BathCellFactory<2> cell_factory( 0.0, centre);

        BidomainWithBathProblem<2> bidomain_problem( &cell_factory );

        DistributedTetrahedralMesh<2,2> mesh;

        mesh.ConstructRegularSlabMesh(0.05, 0.9, 0.9);

        // set the x<0.25 and x>0.75 regions as the bath region
        for (AbstractTetrahedralMesh<2,2>::ElementIterator iter = mesh.GetElementIteratorBegin();
             iter != mesh.GetElementIteratorEnd();
             ++iter)
        {
            double x = iter->CalculateCentroid()[0];
            double y = iter->CalculateCentroid()[1];
            if( (x>0.3) && (x<0.6) && (y>0.3) && (y<0.6) )
            {
                iter->SetAttribute(0);
            }
            else
            {
                if (y<0.2)
                {
                    iter->SetAttribute(2);
                }
                else if (y<0.7)
                {
                    iter->SetAttribute(3);
                }
                else if (y<0.9)
                {
                    iter->SetAttribute(4);
                }
            }
        }

        std::map<unsigned, double> multiple_bath_conductivities;
        multiple_bath_conductivities[2] = 7.0;
        multiple_bath_conductivities[3] = 1.0;
        multiple_bath_conductivities[4] = 0.001;

        HeartConfig::Instance()->SetBathMultipleConductivities(multiple_bath_conductivities);

        double boundary_flux = -3.0e3;
        double start_time = 0.0;
        double duration = 1.0; // of the stimulus, in ms

        HeartConfig::Instance()->SetElectrodeParameters(false, 0, boundary_flux, start_time, duration);

        bidomain_problem.SetMesh(&mesh);
        bidomain_problem.Initialise();

        bidomain_problem.Solve();

        DistributedVector distributed_solution = bidomain_problem.GetSolutionDistributedVector();
        DistributedVector::Stripe voltage(distributed_solution, 0);

        /*
         * We are checking the last time step. This test will only make sure that an AP is triggered.
         */
        bool ap_triggered = false;

        for (DistributedVector::Iterator index = distributed_solution.Begin();
             index!= distributed_solution.End();
             ++index)
        {
            // test V = 0 for all bath nodes and that an AP is triggered in the tissue
            if (HeartRegionCode::IsRegionBath( mesh.GetNode(index.Global)->GetRegion() )) // bath
            {
                TS_ASSERT_DELTA(voltage[index], 0.0, 1e-12);
            }
            else if (voltage[index] > 0.0)//at the last time step
            {
                ap_triggered = true;
            }
        }

        TS_ASSERT(PetscTools::ReplicateBool(ap_triggered));
    }