// currentTide calculation function, takes a DateTime object from real time clock
float TideCalc::currentTide(DateTime now) {
	// Calculate difference between current year and starting year.
	YearIndx = now.year() - startYear;
 	// Calculate hours since start of current year. Hours = seconds / 3600
	currHours = (now.unixtime() - pgm_read_dword_near(&startSecs[YearIndx])) / float(3600);
   // Shift currHours to Greenwich Mean Time
   currHours = currHours + adjustGMT;
   // *****************Calculate current tide height*************
   tideHeight = Datum; // initialize results variable, units of feet.
   for (int harms = 0; harms < 37; harms++) {
       // Step through each harmonic constituent, extract the relevant
       // values of Nodefactor, Amplitude, Equilibrium argument, Kappa
       // and Speed.
       currNodefactor = pgm_read_float_near(&Nodefactor[YearIndx][harms]);
 		currAmp = pgm_read_float_near(&Amp[harms]);
       currEquilarg = pgm_read_float_near(&Equilarg[YearIndx][harms]);
       currKappa = pgm_read_float_near(&Kappa[harms]);
       currSpeed = pgm_read_float_near(&Speed[harms]);
    // Calculate each component of the overall tide equation
    // The currHours value is assumed to be in hours from the start of the
    // year, in the Greenwich Mean Time zone, not the local time zone.
       tideHeight = tideHeight + (currNodefactor * currAmp *
           cos( (currSpeed * currHours + currEquilarg - currKappa) * DEG_TO_RAD));
    }
    //******************End of Tide Height calculation*************
    return tideHeight;  // Output of tideCalc is the tide height, units of feet
}
示例#2
0
// -------------------------------------
FLOAT typeJ::absMV_C( FLOAT tempC ) {
  if( !inrange_C( tempC ) )
    return TC_RANGE_ERR;
  if( ( tempC >= pgm_read_float_near( &range_dir[0][0] ) ) &&
      ( tempC <= pgm_read_float_near( &range_dir[1][0] ) ) )
    return _poly( tempC, &(coeff_dir[0][0]), 9, 2 );
  else
    return _poly( tempC, &(coeff_dir[0][1]), 9, 2 );
};
示例#3
0
// -------------------------------------
FLOAT typeJ::absTemp_C( FLOAT mv ) {
  if ( ! inrange_mV( mv ) )
    return TC_RANGE_ERR;
  uint8_t j;
  uint8_t ind = 0;
  // first figure out which range of values
  for( j = 0; j < 3; j++ ) {
    if( ( mv >= pgm_read_float_near( &range_inv[0][j] ) ) &&
        ( mv <= pgm_read_float_near( &range_inv[1][j] ) ) )
      ind = j;
  }
  return _poly( mv, &(coeff_inv[0][ind]), 9, 3 );
}
示例#4
0
// evaluate polynomial using Horner's rule
// coeff must point to top of selected column of coefficients in nrows x ncols array
FLOAT tcBase::_poly( FLOAT x, const FLOAT* coeff, uint8_t nrows, uint8_t ncols ) {
  uint8_t idx = ( nrows - 1 ) * ncols; // point to the bottom of the column
  FLOAT fx = 0.0; // initialize the summing variable
  for( ; ; ) { // iterate from bottom to top of column
    fx = fx * x + pgm_read_float_near( coeff + idx );
    if( idx == 0 )
      break;
    idx -= ncols; // move up to the next row in the same column
  }
  return fx;
}
示例#5
0
float Turbo_Trig::sinx(int deg) {
    int sign = 1;
    if (deg < 0) {
        deg = -deg;
        sign = -1;
    }
    while(deg > 180) {
        deg -= 180;
        sign *= -1;
    }
    if (deg > 90)
        deg = 180 - deg;
    return (sign * (pgm_read_float_near(SIN_TABLE + deg)));
}
示例#6
0
// ---------------- returns mV corresponding to temp reading
//                  used for cold junction compensation
FLOAT typeK::absMV_C( FLOAT tempC ) {
  FLOAT sum;
  if( !inrange_C( tempC ) )
    return TC_RANGE_ERR;
  if( ( tempC >= pgm_read_float_near( &range_dir[0][0] ) ) &&
      ( tempC <= pgm_read_float_near( &range_dir[1][0] ) ) )
      return _poly( tempC, &(coeff_dir[0][0]), 11, 2 );
  else {
    sum = _poly( tempC, &(coeff_dir[0][1]), 11, 2 );
    return sum + pgm_read_float_near( &a[0] ) *
        exp( pgm_read_float_near( &a[1] ) *
        ( tempC - pgm_read_float_near( &a[2] ) ) *
        ( tempC - pgm_read_float_near( &a[2] ) ) );
  }
}
示例#7
0
void KEMPER_NAMESPACE::loadStompParameters(PartialParameter *parameter, StompInfo *info /* = 0 */)
{
	if (info) {
		parameter->stompInfo = info;
		parameter->stompType = info->type;
	}
	if (!parameter->stompInfo)
		return;
	if (parameter->stompType != parameter->stompInfo->type) {
		parameter->currentOption = 0;
		parameter->currentParam = 0;
		parameter->stompType = parameter->stompInfo->type;
	}
	parameter->paramCount = 0;
	parameter->totalParamCount = parameter->stompInfo->paramCount;
	int startParamIndex = max(parameter->currentParam - (NUMBER_OF_PARAMS_IN_LIST-1)/2, 0);
	parameter->startParamIndex = startParamIndex = max(min(startParamIndex, parameter->totalParamCount-NUMBER_OF_PARAMS_IN_LIST), 0);

	PGM_KemperParam** params = (PGM_KemperParam**)pgm_read_word_near(&AllStomps[parameter->stompInfo->PGM_index].params);

	if (!params) {
		parameter->paramCount = 0;
		parameter->optionCount = 0;
		parameter->totalOptionCount = 0;
		return;
	}

	for (int j=0;j<min(min(parameter->stompInfo->paramCount-startParamIndex, NUMBER_OF_PARAMS_IN_LIST), parameter->totalParamCount-startParamIndex);j++) {
		PGM_KemperParam *param = (PGM_KemperParam*) pgm_read_word_near(&params[startParamIndex+j]);

		parameter->params[j].number = pgm_read_word_near(&param->number);
		parameter->params[j].optionCount = pgm_read_word_near(&param->optionCount);

		strcpy_P(parameter->params[j].name, param->name);
		parameter->paramCount = j+1;
	}

	const PGM_KemperParam *psrc = (PGM_KemperParam*) pgm_read_word_near(&params[parameter->currentParam]);

	KemperParamValue *value = (KemperParamValue*)pgm_read_word_near(&psrc->value);
	if (value) {
		parameter->valueType.id = pgm_read_word_near(&value->id);
		parameter->valueType.minValue = pgm_read_float_near(&value->minValue);
		parameter->valueType.maxValue = pgm_read_float_near(&value->maxValue);
		parameter->valueType.maxParam = pgm_read_word_near(&value->maxParam);
		parameter->valueType.special = pgm_read_word_near(&value->special);
		parameter->valueType.exponential = pgm_read_word_near(&value->exponential);
		strcpy_P(parameter->valueType.suffix, value->suffix);
	}
	else {
		parameter->valueType.id = 0xff;
		parameter->valueType.minValue = 0;
		parameter->valueType.maxValue = 0;
		parameter->valueType.maxParam = 0;
		parameter->valueType.special = false;
		parameter->valueType.exponential = false;
		parameter->valueType.suffix[0] = 0;
	}

	int j = 0;
	parameter->optionCount = 0;
	parameter->totalOptionCount = parameter->params[parameter->currentParam-startParamIndex].optionCount;

	KemperParamOption** options = (KemperParamOption**)pgm_read_word_near(&psrc->options);

	if (parameter->totalOptionCount>0)
	{
		int startOptionIndex = max(parameter->currentOption - (NUMBER_OF_OPTIONS_IN_LIST-1)/2, 0);
		startOptionIndex = min(startOptionIndex, (parameter->totalOptionCount)-NUMBER_OF_OPTIONS_IN_LIST);
		parameter->startOptionIndex = startOptionIndex = max(0, startOptionIndex);
		for (j=0;j<min(min(parameter->totalOptionCount - startOptionIndex, NUMBER_OF_OPTIONS_IN_LIST), parameter->totalOptionCount-startOptionIndex);j++) {

			KemperParamOption* option = (KemperParamOption*)pgm_read_word_near(&options[j+startOptionIndex]);

			parameter->options[j].value = pgm_read_word_near(&option->value);
			strcpy_P(parameter->options[j].name, option->name);
			parameter->optionCount = j+1;
		}
	} else {
		parameter->startOptionIndex = 0;
		parameter->optionCount = 0;
	}
}
float ArduinoProgramMemory::readFloatNear(const void* addr)
{
    return pgm_read_float_near(addr);
}
示例#9
0
double EqualTemperament::pitch( key k )
{
   double f = pgm_read_float_near( freq + k.position() );
   return f * ( 1 << k.octave() );
}