Hard Coded Info contains the simple firmware for users that want to experiment and appreciate smaller code at the expense of features.

The "Hard Coded Info" typ of firmware is intended for experimenters that need a lighter firmware and are OK with having their call sign hard coded in the source code.  It does not support the Serial API that allows the the use of a PC software to set all the data and it only transmits on a single frequency.
master
Harry 2018-07-23 21:48:29 +02:00 zatwierdzone przez GitHub
rodzic 33243d953a
commit 11763bb6cf
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
1 zmienionych plików z 697 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,697 @@
//Software for Zachtek for the WSPR-TX_LP1 product withh product number 1011. This board is also known as "WSPR Transmitter Experimenters version"
//There are two different flawors of firmware for this board.
//1: This code with hardcoded Callsign and Power data that just transmitt on one single band. It is smaller in size and simpler in many ways so for
// experimenters that want to modify the code, expand, add sensors etc etc, this might be easier to use.
//2: The regular version that is designed to be used with a PC software to set all the data like callsign, power level, band hopping etc
// To acheive this it uses a Serial API and stores settings in EEPROM. It can do more but it is much bigger and can be hard to understand for the beginner.
//The Version of this software is stored in the constant "softwareversion" and is displayed on the Serialport att startup
//
//To compile you need to install several libraries, se below in the #include section what they are and download them using The Library manager in the Arduino IDE or use the direct URL
//For Arduino Pro Mini 3.3V 8MHz.
//
// Version History
// 1.05 initial Release
//
//The WSPR coding is based on Jason Mildrums example code. See his orgiginal Copyright text below the line.
//Harry "deBug" Zachrisson of ZachTek 2018
//-----------------------------------------------------------------
// WSPR beacon for Arduino, by Jason Milldrum NT7S.
// Original code based on Feld Hell beacon for Arduino by Mark
// Vandewettering K6HX, adapted for the Si5351A by Robert
// Liesenfeld AK6L <ak6l@ak6l.org>.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject
// to the following conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
#include <TinyGPS++.h> //TinyGPS++ library by Mikal Hart https://github.com/mikalhart/TinyGPSPlus
#include <JTEncode.h> //JTEncode by NT7S https://github.com/etherkit/JTEncode
#include <SoftwareSerial.h> //Arduino SoftSerial
void i2cInit();
uint8_t i2cSendRegister(uint8_t reg, uint8_t data);
uint8_t i2cReadRegister(uint8_t reg, uint8_t *data);
#define I2C_START 0x08
#define I2C_START_RPT 0x10
#define I2C_SLA_W_ACK 0x18
#define I2C_SLA_R_ACK 0x40
#define I2C_DATA_ACK 0x28
#define I2C_WRITE 0b11000000
#define I2C_READ 0b11000001
#define SI5351A_H
#define SI_CLK0_CONTROL 16 // Register definitions
#define SI_CLK1_CONTROL 17
#define SI_CLK2_CONTROL 18
#define SI_SYNTH_PLL_A 26
#define SI_SYNTH_PLL_B 34
#define SI_SYNTH_MS_0 42
#define SI_SYNTH_MS_1 50
#define SI_SYNTH_MS_2 58
#define SI_PLL_RESET 177
#define SI_R_DIV_1 0b00000000 // R-division ratio definitions
#define SI_R_DIV_2 0b00010000
#define SI_R_DIV_4 0b00100000
#define SI_R_DIV_8 0b00110000
#define SI_R_DIV_16 0b01000000
#define SI_R_DIV_32 0b01010000
#define SI_R_DIV_64 0b01100000
#define SI_R_DIV_128 0b01110000
#define SI_CLK_SRC_PLL_A 0b00000000
#define SI_CLK_SRC_PLL_B 0b00100000
#define XTAL_FREQ 25000026 // Crystal frequency for a certain board in Hertz, change to fit your induvidual TCXO
//defines for TX Frequeny of WSPR on the HAM bands
#define WSPR_TONE_SPACING 146 // ~1.46 Hz Tone spacng in centiHz
#define WSPR_DELAY 683 // Delay value for WSPR delay in milliseconds
#define WSPR_FREQ23cm 18521450000ULL //23cm 1296.501,500MHz (7th overtone, not implemented)
#define WSPR_FREQ70cm 14410050000ULL //70cm 432.301,500MHz (3rd overtone, not implemented)
#define WSPR_FREQ2m 14449000000ULL //2m 144.490,000MHz
#define WSPR_FREQ4m 5029450000ULL //6m 50.294,500MHz
#define WSPR_FREQ17m 1810610000ULL //17m 18.106,100MHz
#define WSPR_FREQ20m 1409710000ULL //20m 14.097,100MHz
#define WSPR_FREQ30m 1014020000ULL //30m 10.140,200MHz
#define WSPR_FREQ40m 704010000ULL //40m 7.040,100MHz
#define WSPR_FREQ80m 359410000ULL //80m 3.394,100MHz
#define WSPR_FREQ160m 183810000ULL //160m 1.838,100MHz
#define WSPR_FREQ630m 47570000ULL //630m 475.700kHz
#define WSPR_FREQ2190m 13750000ULL //2190m 137.500kHz
// Hardware defines
#define LEDIndicator1 4 //Yellow LED to indicator that blinks at different rates depending on GPS Lock, waiting for time to go to top of minute, Transmitting etc
#define TransmitLED 8 //Red LED next to RF out SMA that will turn on when Transmitting
const char softwareversion[] = "1.05" ; //Version of this program, sent to serialport at startup
// Enumerations
// Class instantiation
JTEncode jtencode;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial GPSSerial(2,3); //GPS Serial port, RX on pin 2, TX on pin 3
void si5351aOutputOff(uint8_t clk);
void si5351aSetFrequency(uint32_t frequency);
//*********************************************************************************************
//----------------------- Set Transmit Frequency and Amateur call sign here--------------------
//*********************************************************************************************
const uint64_t WSPR_DEFAULT_FREQ = WSPR_FREQ20m; // Set this to one of the defined WSPR band constants, or set to any frequency in centiHertz
char MHLocator[] = "AA68BB";// Dont change, this is only here to allocate memory, will be changed by the GPS position and Maidenhead calculations.
char call[] = "SM0AAA"; //**********Set your call sign here **************
char loc[] = "AB01"; //If you dont want to use the GPS provided locator you can hard code a locator here, 4 chars only. You will still need the GPS for timing - Only used if LocatorByGPS=false
boolean LocatorByGPS=true; //Set to false to disable automatic location by GPS and switch to use the "loc" value
uint8_t dbm = 23; //Output power in dBm. The WSPR-TX gives out about 24dBm after Low Pass filtering so 23 is closest value in WSPR coding, change this if you have an attenuater or Amplifier connected
//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
uint8_t tx_buffer[180];
uint8_t symbol_count;
uint16_t tone_delay, tone_spacing;
uint64_t freq;
void setup()
{
// Set the proper frequency, tone spacing, symbol count, and
// tone delay depending on mode
freq = WSPR_DEFAULT_FREQ;
symbol_count = WSPR_SYMBOL_COUNT; // From the library defines
tone_spacing = WSPR_TONE_SPACING;
tone_delay = WSPR_DELAY;
bool i2c_found;
//Initialize Arduinos Serial port
Serial.begin (9600);
delay(500);//Wait for Serialport to be initialized properly
GPSSerial.begin(9600); // //The GPS Serial port
//Output Initialization text on the serial port
Serial.print(F("Zachtek WSPR-TX_LP1 -Hard Codeed Info- Software version: "));
Serial.println(softwareversion);
Serial.println(F("Initializing.."));
Serial.print(F("Callsign set to "));
Serial.println(call);
Serial.println(F("Maidenhead postion will be set by GPS"));
Serial.print(F("Power Data set to "));
Serial.print(dbm);
Serial.println(F("dBm"));
Serial.print (F("Frequency set to "));
Serial.print (uint64ToStr((freq/100ULL),false));
Serial.println(F("Hz +/-100Hz random at every TX"));
Serial.println(F("Initializing.."));
pinMode(TransmitLED,OUTPUT);
pinMode(LEDIndicator1, OUTPUT);
Serial.println(F("Blinking Yellow LED indicator"));
for (int i=0; i <= 30; i++){
digitalWrite(LEDIndicator1, HIGH);
delay (20);
digitalWrite(LEDIndicator1, LOW);
delay (20);;
}
Serial.println(F("Initializing I2C"));
i2cInit();
Serial.println(F("Initializing Si5351"));
si5351aSetFrequency(2000000000ULL);
//delay(10000);
si5351aOutputOff(SI_CLK0_CONTROL);
// Encode the message in the transmit buffer
// This is RAM intensive and should be done separately from other subroutines
//set_tx_buffer();
Serial.println(F("Initialization is complete."));
Serial.println();
}
void loop()
{
static double Lat;
static double Lon;
static int GPSH;
static int GPSM;
static int GPSS;
//encode ();
while (GPSSerial.available()) {
gps.encode(GPSSerial.read());
if (gps.location.isUpdated())
{
//Serial.println(F("Is updated"));
GPSH=gps.time.hour();
GPSM=gps.time.minute();
GPSS=gps.time.second();
if (LocatorByGPS)
{
//Serial.println(F("LocatorByGPS"));
Lat=gps.location.lat();
// Serial.println(F("Lat set"));
Lon=gps.location.lng();
//Serial.print(F("Lat, Lon= "));
//Serial.print (Lat);
//Serial.println (Lon);
//Serial.print(" ");
// Serial.println(F("Before CalcLocator"));
calcLocator (Lat,Lon);
// Serial.println(F("After CalcLocator"));
Serial.print (F("GPS Fix accuired - Maidenhead locator is "));
Serial.print(MHLocator);
loc[0]=MHLocator[0]; loc[1]=MHLocator[1];loc[2]=MHLocator[2];loc[3]=MHLocator[3];
Serial.print (F(" (using "));
Serial.print(loc);
Serial.println (F(")"));
LocatorByGPS=false;
long seed= (long) (((long)Lat*10000) + ((long)Lon*10000));
randomSeed(seed);
// Encode the message in the transmit buffer so we are prepared to transmit
// This is RAM intensive and should be done separately from other subroutines
set_tx_buffer();
Serial.println (F("Waiting for start of even minute to start WSPR transmission block"));
}
if ((GPSS == 0) && ((GPSM % 2) == 0))//If second is zero at even minute then start WSPR transmission
{
Serial.println(F("Top of even minute."));
Serial.print(F("Transmitting for 1 Minute and 50 seconds at frequency :"));
freq=WSPR_DEFAULT_FREQ + (100ULL* random (-100,100));
Serial.print(uint64ToStr(freq/100,false));
Serial.println(F("Hz"));
encode ();
smartdelay(70000);//Pause for some time to give a duty cycle on the transmit. 2000=100%, 20000=50%, 130000=33%
}
else //Dubble-blink to indicate waiting for top of minute
{
Serial.print (GPSH);
Serial.print (F(":"));
Serial.print (GPSM);
Serial.print (F(":"));
Serial.print (GPSS);
Serial.println( );
//Serial.println (F("Waiting for WSPR timeslot."));
digitalWrite(LEDIndicator1, HIGH);
smartdelay (100);
digitalWrite(LEDIndicator1, LOW);
smartdelay (100);
digitalWrite(LEDIndicator1, HIGH);
smartdelay (100);
digitalWrite(LEDIndicator1, LOW);
smartdelay(300);
}
}
if (gps.location.isValid())
{
//digitalWrite(LEDIndicator1, HIGH); // turn the LED on
}
else
{
// //singelblink to indicate waiting for GPS Lock
digitalWrite(LEDIndicator1, HIGH); // turn the LED on
smartdelay(100);
digitalWrite(LEDIndicator1, LOW); // turn the LED off
Serial.println(F("Waiting for GPS location fix. "));
smartdelay(500);
}
}
}
// Loop through the string, transmitting one character at a time.
void encode()
{
uint8_t i;
unsigned long startmillis;
unsigned long endmillis;
// Reset the tone to the base frequency and turn on the output
// Now transmit the channel symbols
digitalWrite(LEDIndicator1, HIGH);
startmillis=millis();
for(i = 0; i < symbol_count; i++)
{
endmillis=startmillis + ((i+1) * (unsigned long) tone_delay) ;
//Serial.print(i);
//Serial.print(" ");
//Serial.print(F("Freq is="));
//Serial.println(freq);
uint64_t tonefreq;
tonefreq=freq + ((tx_buffer[i] * tone_spacing));
//Serial.print(F("Tone Freq is="));
//Serial.println(uint64ToStr(tonefreq,false));
si5351aSetFrequency(tonefreq);
//delay (10000);
//si5351aChangeFrequency(tonefreq);
//wait untill tone is transmitted for the correct amount of time
while (millis() < endmillis){
//just wait
}
}
// Turn off the output
// Switches off Si5351a output
si5351aOutputOff(SI_CLK0_CONTROL);
digitalWrite(LEDIndicator1, LOW);
Serial.println(F("TX Off"));
}
void set_tx_buffer()
{
// Clear out the transmit buffer
memset(tx_buffer, 0, sizeof(tx_buffer));
jtencode.wspr_encode(call, loc, dbm, tx_buffer);
}
//Maidenhead code from Ossi Väänänen https://ham.stackexchange.com/questions/221/how-can-one-convert-from-lat-long-to-grid-square
void calcLocator(double lat, double lon) {
int o1, o2, o3;
int a1, a2, a3;
double remainder;
// longitude
remainder = lon + 180.0;
o1 = (int)(remainder / 20.0);
remainder = remainder - (double)o1 * 20.0;
o2 = (int)(remainder / 2.0);
remainder = remainder - 2.0 * (double)o2;
o3 = (int)(12.0 * remainder);
// latitude
remainder = lat + 90.0;
a1 = (int)(remainder / 10.0);
remainder = remainder - (double)a1 * 10.0;
a2 = (int)(remainder);
remainder = remainder - (double)a2;
a3 = (int)(24.0 * remainder);
MHLocator[0] = (char)o1 + 'A';
MHLocator[1] = (char)a1 + 'A';
MHLocator[2] = (char)o2 + '0';
MHLocator[3] = (char)a2 + '0';
MHLocator[4] = (char)o3 + 'A';
MHLocator[5] = (char)a3 + 'A';
}
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (GPSSerial.available())
gps.encode(GPSSerial.read());
} while (millis() - start < ms);
}
uint8_t i2cStart()
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) ;
return (TWSR & 0xF8);
}
void i2cStop()
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
while ((TWCR & (1<<TWSTO))) ;
}
uint8_t i2cByteSend(uint8_t data)
{
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) ;
return (TWSR & 0xF8);
}
uint8_t i2cByteRead()
{
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) ;
return (TWDR);
}
uint8_t i2cSendRegister(uint8_t reg, uint8_t data)
{
uint8_t stts;
stts = i2cStart();
if (stts != I2C_START) return 1;
stts = i2cByteSend(I2C_WRITE);
if (stts != I2C_SLA_W_ACK) return 2;
stts = i2cByteSend(reg);
if (stts != I2C_DATA_ACK) return 3;
stts = i2cByteSend(data);
if (stts != I2C_DATA_ACK) return 4;
i2cStop();
return 0;
}
uint8_t i2cReadRegister(uint8_t reg, uint8_t *data)
{
uint8_t stts;
stts = i2cStart();
if (stts != I2C_START) return 1;
stts = i2cByteSend(I2C_WRITE);
if (stts != I2C_SLA_W_ACK) return 2;
stts = i2cByteSend(reg);
if (stts != I2C_DATA_ACK) return 3;
stts = i2cStart();
if (stts != I2C_START_RPT) return 4;
stts = i2cByteSend(I2C_READ);
if (stts != I2C_SLA_R_ACK) return 5;
*data = i2cByteRead();
i2cStop();
return 0;
}
// Init TWI (I2C)
//
void i2cInit()
{
TWBR = 92;
TWSR = 0;
TWDR = 0xFF;
PRR = 0;
}
//
// Set up specified PLL with mult, num and denom
// mult is 15..90
// num is 0..1,048,575 (0xFFFFF)
// denom is 0..1,048,575 (0xFFFFF)
//
void setupPLL(uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom)
{
uint32_t P1; // PLL config register P1
uint32_t P2; // PLL config register P2
uint32_t P3; // PLL config register P3
P1 = (uint32_t)(128 * ((float)num / (float)denom));
P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
P2 = (uint32_t)(128 * ((float)num / (float)denom));
P2 = (uint32_t)(128 * num - denom * P2);
P3 = denom;
i2cSendRegister(pll + 0, (P3 & 0x0000FF00) >> 8);
i2cSendRegister(pll + 1, (P3 & 0x000000FF));
i2cSendRegister(pll + 2, (P1 & 0x00030000) >> 16);
i2cSendRegister(pll + 3, (P1 & 0x0000FF00) >> 8);
i2cSendRegister(pll + 4, (P1 & 0x000000FF));
i2cSendRegister(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 &
0x000F0000) >> 16));
i2cSendRegister(pll + 6, (P2 & 0x0000FF00) >> 8);
i2cSendRegister(pll + 7, (P2 & 0x000000FF));
}
//
// Set up MultiSynth with integer Divider and R Divider
// R Divider is the bit value which is OR'ed onto the appropriate
// register, it is a #define in si5351a.h
//
void setupMultisynth(uint8_t synth, uint32_t Divider, uint8_t rDiv)
{
uint32_t P1; // Synth config register P1
uint32_t P2; // Synth config register P2
uint32_t P3; // Synth config register P3
P1 = 128 * Divider - 512;
P2 = 0; // P2 = 0, P3 = 1 forces an integer value for the Divider
P3 = 1;
i2cSendRegister(synth + 0, (P3 & 0x0000FF00) >> 8);
i2cSendRegister(synth + 1, (P3 & 0x000000FF));
i2cSendRegister(synth + 2, ((P1 & 0x00030000) >> 16) | rDiv);
i2cSendRegister(synth + 3, (P1 & 0x0000FF00) >> 8);
i2cSendRegister(synth + 4, (P1 & 0x000000FF));
i2cSendRegister(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 &
0x000F0000) >> 16));
i2cSendRegister(synth + 6, (P2 & 0x0000FF00) >> 8);
i2cSendRegister(synth + 7, (P2 & 0x000000FF));
}
//
// Switches off Si5351a output
// Example: si5351aOutputOff(SI_CLK0_CONTROL);
// will switch off output CLK0
//
void si5351aOutputOff(uint8_t clk)
{
digitalWrite(TransmitLED, LOW);
i2cSendRegister(clk, 0x80); // Refer to SiLabs AN619 to see
//bit values - 0x80 turns off the output stage
}
//
// Set CLK0 output ON and to the specified frequency
// Frequency is in the range 10kHz to 150MHz and given in centiHertz (hundreds of Hertz)
// Example: si5351aSetFrequency(1000000200);
// will set output CLK0 to 10.000,002MHz
//
// This example sets up PLL A
// and MultiSynth 0
// and produces the output on CLK0
//
void si5351aSetFrequency(uint64_t frequency) //Frequency is in centiHz
{
static uint64_t oldFreq;
int32_t FreqChange;
uint64_t pllFreq;
uint32_t xtalFreq = XTAL_FREQ;
uint32_t l;
float f;
uint8_t mult;
uint32_t num;
uint32_t denom;
uint32_t Divider;
uint8_t rDiv;
digitalWrite(TransmitLED, HIGH);
// Serial.print (F("Freq is="));
// Serial.println (uint64ToStr(frequency,false));
if (frequency>100000000) { //If higher than 1MHz then set output divider to 1
rDiv=SI_R_DIV_1;
Divider = 90000000000ULL / frequency;// Calculate the division ratio. 900MHz is the maximum internal (expressed as deciHz)
//Serial.print (F("Divider="));
//Serial.println (Divider);
pllFreq = Divider * frequency; // Calculate the pllFrequency:
//the Divider * desired output frequency
//Serial.print (F("pllFreq="));
//Serial.println (uint64ToStr(pllFreq,false));
mult = pllFreq / (xtalFreq*100UL); // Determine the multiplier to
//Serial.print (F("mult="));
//Serial.println (mult);
//get to the required pllFrequency
l = pllFreq % (xtalFreq*100UL); // It has three parts:
//Serial.print (F("l="));
//Serial.println (l);
f = l; // mult is an integer that must be in the range 15..90
//Serial.print (F("f="));
//Serial.println (f);
f *= 1048575; // num and denom are the fractional parts, the numerator and denominator
//Serial.print (F("f="));
//Serial.println (f);
f /= xtalFreq; // each is 20 bits (range 0..1048575)
//Serial.print (F("f="));
//Serial.println (f);
num = f; // the actual multiplier is mult + num / denom
//Serial.print (F("num="));
//Serial.println (num);
denom = 1048575; // For simplicity we set the denominator to the maximum 1048575
num=num/100;
}
else // lower freq than 1MHz - use output Divider set to 128
{
rDiv=SI_R_DIV_128;
frequency=frequency*128ULL; //Set base freq 128 times higher as we are dividing with 128 in the last output stage
Divider = 90000000000ULL / frequency;// Calculate the division ratio. 900,000,000 is the maximum internal
pllFreq = Divider * frequency; // Calculate the pllFrequency:
//the Divider * desired output frequency
mult = pllFreq / (xtalFreq*100UL); // Determine the multiplier to
//get to the required pllFrequency
l = pllFreq % (xtalFreq*100UL); // It has three parts:
//Serial.print (F("l="));
//Serial.println (l);
f = l; // mult is an integer that must be in the range 15..90
//Serial.print (F("f="));
//Serial.println (f);
f *= 1048575; // num and denom are the fractional parts, the numerator and denominator
//Serial.print (F("f="));
//Serial.println (f);
f /= xtalFreq; // each is 20 bits (range 0..1048575)
//Serial.print (F("f="));
//Serial.println (f);
num = f; // the actual multiplier is mult + num / denom
//Serial.print (F("num="));
//Serial.println (num);
denom = 1048575; // For simplicity we set the denominator to the maximum 1048575
num=num/100;
}
// Set up PLL A with the calculated multiplication ratio
setupPLL(SI_SYNTH_PLL_A, mult, num, denom);
// Set up MultiSynth Divider 0, with the calculated Divider.
// The final R division stage can divide by a power of two, from 1..128.
// reprented by constants SI_R_DIV1 to SI_R_DIV128 (see si5351a.h header file)
// If you want to output frequencies below 1MHz, you have to use the
// final R division stage
setupMultisynth(SI_SYNTH_MS_0, Divider, rDiv);
// Reset the PLL. This causes a glitch in the output. For small changes to
// the parameters, you don't need to reset the PLL, and there is no glitch
FreqChange=frequency-oldFreq;
if ( abs(FreqChange)> 100000) //If changed more than 1kHz then reset PLL (completely arbitrary choosen)
{
i2cSendRegister(SI_PLL_RESET, 0xA0);
}
// Finally switch on the CLK0 output (0x4F)
// and set the MultiSynth0 input to be PLL A
i2cSendRegister(SI_CLK0_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
oldFreq=frequency;
}
/*
uint64_t StrTouint64_t (String InString)
{
uint64_t y = 0;
for (int i = 0; i < InString.length(); i++) {
char c = InString.charAt(i);
if (c < '0' || c > '9') break;
y *= 10;
y += (c - '0');
}
return y;
}
*/
String uint64ToStr (uint64_t p_InNumber, boolean p_LeadingZeros)
{
char l_HighBuffer[7]; //6 digits + null terminator char
char l_LowBuffer[7]; //6 digits + null terminator char
char l_ResultBuffer [13]; //12 digits + null terminator char
String l_ResultString = "";
uint8_t l_Digit;
sprintf(l_HighBuffer, "%06lu", p_InNumber / 1000000L); //Convert high part of 64bit unsigned integer to char array
sprintf(l_LowBuffer, "%06lu", p_InNumber % 1000000L); //Convert low part of 64bit unsigned integer to char array
l_ResultString = l_HighBuffer;
l_ResultString = l_ResultString + l_LowBuffer; //Copy the 2 part result to a string
if (!p_LeadingZeros) //If leading zeros should be romeved
{
l_ResultString.toCharArray(l_ResultBuffer, 13);
for (l_Digit = 0; l_Digit < 12; l_Digit++ )
{
if (l_ResultBuffer[l_Digit] == '0')
{
l_ResultBuffer[l_Digit] = ' '; // replace zero with a space character
}
else
{
break; //We have found all the leading Zeros, exit loop
}
}
l_ResultString = l_ResultBuffer;
l_ResultString.trim();//Remove all leading spaces
}
return l_ResultString;
}