Arduino Uno convert code to ESP32 help

Folny82
Posts: 7
Joined: Wed Feb 07, 2018 1:56 am

Arduino Uno convert code to ESP32 help

Postby Folny82 » Wed Jun 06, 2018 4:11 pm

Hello Friends

Please give me some advice on the code I'm trying to adjust for ESP32 for a long time but still does not want to work properly please advise me how to modify line 38 (uint8_t ctr = TCNT0;) to work correctly.

here is my code for ESP32 who does not want to work and flood code for Arduino Uno https://github.com/dc42/arduino/blob/ma ... tector.ino

Code: Select all

hw_timer_t * timer0 = NULL;
portMUX_TYPE timerMux0 = portMUX_INITIALIZER_UNLOCKED;

volatile uint8_t stat = 0; 

#define TIMER1_TOP  (8) 
       
uint8_t TxCoilPin = 26;
const int ButtonPin = 36;  // encoder button, also IN0 for waking up from sleep mode
const int receiverInputPin = 39;

int16_t bins[4];                 // bins used to accumulate ADC readings, one for each of the 4 phases
uint16_t numSamples = 0;
const uint16_t numSamplesToAverage = 1024;

volatile int16_t averages[4];    // when we've accumulated enough readings in the bins, the ISR copies them to here and starts again
volatile uint32_t ticks = 0;     // system tick counter for timekeeping
volatile bool sampleReady = false;  // indicates that the averages array has been updated

int16_t calib[4];                // values (set during calibration) that we subtract from the averages

volatile uint8_t lastctr;
volatile uint16_t misses = 0;    // this counts how many times the ISR has been executed too late. Should remain at zero if everything is working properly.

const double halfRoot2 = sqrt(0.5);
const double quarterPi = 3.1415927/4.0;
const double radiansToDegrees = 180.0/3.1415927;

const float phaseAdjust = (45.0 * 32.0)/(float)(TIMER1_TOP + 1);

float threshold = 10.0;          // lower = greater sensitivity. 10 is just about usable with a well-balanced coil.
                                 // The user will be able to adjust this via a pot or rotary encoder.
void IRAM_ATTR onTimer0()
{
  stat=1-stat;
  digitalWrite(TxCoilPin, stat); 
  ++ticks;
  uint8_t ctr = // ??? TCNT0;
  int16_t val = map(analogRead(receiverInputPin), 0, 1023, 0, 255); 
  if (ctr != ((lastctr + 1) & 7))
  {
    ++misses;
  }
  lastctr = ctr;
  int16_t *p = &bins[ctr & 3];
  if (ctr < 4)
  {
    *p += (val);
    if (*p > 15000) *p = 15000;
  }
  else
  {
    *p -= val;
    if (*p < -15000) *p = -15000;
  } 
  if (ctr == 7)
  {
    ++numSamples;
    if (numSamples == numSamplesToAverage)
    {
      numSamples = 0;
      if (!sampleReady)      // if previous sample has been consumed
      {
        memcpy((void*)averages, bins, sizeof(averages));
        sampleReady = true;
      }
      memset(bins, 0, sizeof(bins));
    }
  }
}

void setup()
{
  pinMode(ButtonPin, INPUT_PULLUP);
  pinMode(TxCoilPin, OUTPUT);      // timer 0 output, square wave to drive transmit coil  
  digitalWrite(TxCoilPin, LOW);  
 
  analogReadResolution(10);
  //analogSetWidth(10); 
  analogSetAttenuation(ADC_11db);
  //analogSetClockDiv(1);
  //analogSetSamples(8);

 /*
  analogReadResolution(12);             // Sets the sample bits and read resolution, default is 12-bit (0 - 4095), range is 9 - 12 bits
  analogSetWidth(12);                   // Sets the sample bits and read resolution, default is 12-bit (0 - 4095), range is 9 - 12 bits
                                        //  9-bit gives an ADC range of 0-511
                                        // 10-bit gives an ADC range of 0-1023
                                        // 11-bit gives an ADC range of 0-2047
                                        // 12-bit gives an ADC range of 0-4095
  analogSetCycles(8);                   // Set number of cycles per sample, default is 8 and provides an optimal result, range is 1 - 255
  analogSetSamples(1);                  // Set number of samples in the range, default is 1, it has an effect on sensitivity has been multiplied
  analogSetClockDiv(1);                 // Set the divider for the ADC clock, default is 1, range is 1 - 255
  analogSetAttenuation(ADC_11db);       // Sets the input attenuation for ALL ADC inputs, default is ADC_11db, range is ADC_0db, ADC_2_5db, ADC_6db, ADC_11db
  analogSetPinAttenuation(VP,ADC_11db); // Sets the input attenuation, default is ADC_11db, range is ADC_0db, ADC_2_5db, ADC_6db, ADC_11db
                                        // ADC_0db provides no attenuation so IN/OUT = 1 / 1 an input of 3 volts remains at 3 volts before ADC measurement
                                        // ADC_2_5db provides an attenuation so that IN/OUT = 1 / 1.34 an input of 3 volts is reduced to 2.238 volts before ADC measurement
                                        // ADC_6db provides an attenuation so that IN/OUT = 1 / 2 an input of 3 volts is reduced to 1.500 volts before ADC measurement
                                        // ADC_11db provides an attenuation so that IN/OUT = 1 / 3.6 an input of 3 volts is reduced to 0.833 volts before ADC measurement
  adcAttachPin(VP);                     // Attach a pin to ADC (also clears any other analog mode that could be on), returns TRUE/FALSE result 
  adcStart(VP);                         // Starts an ADC conversion on attached pin's bus
  adcBusy(VP);                          // Check if conversion on the pin's ADC bus is currently running, returns TRUE/FALSE result 
  adcEnd(VP);                           // Get the result of the conversion (will wait if it have not finished), returns 16-bit integer result
  */

  timer0 = timerBegin(0,625, true);  // timer 0, MWDT clock period = 12.5 ns * TIMGn_Tx_WDT_CLK_PRESCALE -> 12.5 ns * 80 -> 1000 ns = 1 us, countUp
  timerAttachInterrupt(timer0, &onTimer0, true); // edge (not level) triggered 
  timerAlarmWrite(timer0, TIMER1_TOP, true); // 2000000 * 1 us = 2 s, autoreload true
  timerAlarmEnable(timer0); // enable
    
  while (!sampleReady) {}    // discard the first sample
  misses = 0;
  sampleReady = false;
  
  Serial.begin(115200); 
}

void loop()
{

  while (!sampleReady) {}
  uint32_t oldTicks = ticks;
  
  if (digitalRead(ButtonPin) == LOW)
  {
    // Calibrate button pressed. We save the current phase detector outputs and subtract them from future results.
    // This lets us use the detector if the coil is slightly off-balance.
    // It would be better to everage several samples instead of taking just one.
    for (int i = 0; i < 4; ++i)
    {
      calib[i] = averages[i];
    }
    sampleReady = false;
    Serial.print("Calibrated: ");
    for (int i = 0; i < 4; ++i)
    {
      Serial.write(' ');
      Serial.print(calib[i]);
    }
    Serial.println();
  }
  else
  {  
    for (int i = 0; i < 4; ++i)
    {
      averages[i] -= calib[i];
    }
    const double f = 200.0;
    
    // Massage the results to eliminate sensitivity to the 3rd harmonic, and divide by 200
    double bin0 = (averages[0] + halfRoot2 * (averages[1] - averages[3]))/f;
    double bin1 = (averages[1] + halfRoot2 * (averages[0] + averages[2]))/f;
    double bin2 = (averages[2] + halfRoot2 * (averages[1] + averages[3]))/f;
    double bin3 = (averages[3] + halfRoot2 * (averages[2] - averages[0]))/f;
    sampleReady = false;          // we've finished reading the averages, so the ISR is free to overwrite them again

    double amp1 = sqrt((bin0 * bin0) + (bin2 * bin2));
    double amp2 = sqrt((bin1 * bin1) + (bin3 * bin3));
    double ampAverage = (amp1 + amp2)/2.0;
    
    // The ADC sample/hold takes place 2 clocks after the timer overflow
    double phase1 = atan2(bin0, bin2) * radiansToDegrees + 45.0;
    double phase2 = atan2(bin1, bin3) * radiansToDegrees;
  
    if (phase1 > phase2)
    {
      double temp = phase1;
      phase1 = phase2;
      phase2 = temp;
    }
    
    double phaseAverage = ((phase1 + phase2)/2.0) - phaseAdjust;
    if (phase2 - phase1 > 180.0)
    { 
      if (phaseAverage < 0.0)
      {
        phaseAverage += 180.0;
      }
      else
      {
        phaseAverage -= 180.0;
      }
    }
        
    // For diagnostic purposes, print the individual bin counts and the 2 indepedently-calculated gains and phases                                                        
    Serial.print(misses);
    Serial.write(' ');
    
    if (bin0 >= 0.0) Serial.write(' ');
    Serial.print(bin0, 2);
    Serial.write(' ');
    if (bin1 >= 0.0) Serial.write(' ');
    Serial.print(bin1, 2);
    Serial.write(' ');
    if (bin2 >= 0.0) Serial.write(' ');
    Serial.print(bin2, 2);
    Serial.write(' ');
    if (bin3 >= 0.0) Serial.write(' ');
    Serial.print(bin3, 2);
    Serial.print("    ");
    Serial.print(amp1, 2);
    Serial.write(' ');
    Serial.print(amp2, 2);
    Serial.write(' ');
    if (phase1 >= 0.0) Serial.write(' ');
    Serial.print(phase1, 2);
    Serial.write(' ');
    if (phase2 >= 0.0) Serial.write(' ');
    Serial.print(phase2, 2);
    Serial.print("    ");
    
    // Print the final amplitude and phase, which we use to decide what (if anything) we have found)
    if (ampAverage >= 0.0) Serial.write(' ');
    Serial.print(ampAverage, 1);
    Serial.write(' ');
    if (phaseAverage >= 0.0) Serial.write(' ');
    Serial.print((int)phaseAverage);
    
    // Decide what we have found and tell the user
    if (ampAverage >= threshold)
    {
      // When held in line with the centre of the coil:
      // - non-ferrous metals give a negative phase shift, e.g. -90deg for thick copper or aluminium, a copper olive, -30deg for thin alumimium.
      // Ferrous metals give zero phase shift or a small positive phase shift.
      // So we'll say that anything with a phase shift below -20deg is non-ferrous.
      if (phaseAverage < -20.0)
      {
        Serial.print(" Non-ferrous");
      }
      else
      {
        Serial.print(" Ferrous");
      }
      float temp = ampAverage;
      while (temp > threshold)
      {
        Serial.write('!');
        temp -= (threshold/2);
      }
    }   
    Serial.println();
   }
  while (ticks - oldTicks < 16000)
  {
  }
}

Who is online

Users browsing this forum: Baidu [Spider] and 57 guests