// ///////////////////////////////////////////////////////////////////// // // ARDUINO/Genuino EVERY Sketch for "TOBIMOD" // https://www.changpuak.ch/electronics/Arduino-Tobimod.php // // WRITTEN 29.12.2565 BY ALEXANDER SSE FRANK // // The Serial Parser is from here : // Easy_Diseqc V1.2, Monstein ETH Zurich, 20.06.2018 // // ///////////////////////////////////////////////////////////////////// #include const byte AT24C01_ADR = 0x50 ; // EEPROM const bool debug = true ; // SERIAL String buffer ; char tempbuf[80] ; // keeps the command temporary until CRLF // ///////////////////////////////////////////////////////////////////// // DDS (AD9912) ROUTINES // // The AD9912 serial control port can be configured for a single // bidirectional I/O pin (SDIO only) or for two unidirectional I/O pins // SDIO and SDO. THIS IS WHAT WE USE. // ///////////////////////////////////////////////////////////////////// const float MINFREQ = 5.0 ; // MHz const float MAXFREQ = 400.0 ; // MHz float FREQ = MINFREQ ; byte ASF = 0x49 ; const int SCLK = A4 ; const int SDIO = A5 ; const int SDO = A6 ; const int CSB = A7 ; const int IO_UPDATE = 2 ; void Write_Byte_DDS(unsigned int address, byte payload) { // write operation (I15 = 0) // W1 = 0, W0 = 0 >>> 1 Byte unsigned int LO = address & 0x00FF ; unsigned int HI = (address & 0x1F00) >> 8 ; HI |= 0x00 ; // WRITE :-) digitalWrite(CSB, LOW) ; shiftOut(SDIO, SCLK, MSBFIRST, HI) ; shiftOut(SDIO, SCLK, MSBFIRST, LO) ; shiftOut(SDIO, SCLK, MSBFIRST, payload) ; digitalWrite(CSB, HIGH) ; } void Init_DDS() { Write_Byte_DDS(0x0000, 0x81) ; // SDO active, MSB first Write_Byte_DDS(0x0001, 0x00) ; Write_Byte_DDS(0x0002, 0x02) ; Write_Byte_DDS(0x0003, 0x09) ; Write_Byte_DDS(0x0004, 0x00) ; // Read buffer register Write_Byte_DDS(0x0005, 0x00) ; Write_Byte_DDS(0x0010, 0x80) ; // HSTL + CMOS output = OFF, PLL = ON Write_Byte_DDS(0x0012, 0x00) ; Write_Byte_DDS(0x0013, 0x00) ; Write_Byte_DDS(0x0020, 0x12) ; // N=20 * 2 = 40 * 25 MHz = 1 GHz Write_Byte_DDS(0x0022, 0x84) ; // Automatic VCO range selection, 250 μA Write_Byte_DDS(0x0104, 0x00) ; Write_Byte_DDS(0x0105, 0x00) ; Write_Byte_DDS(0x0106, 0x00) ; // FTW GOES HERE Write_Byte_DDS(0x01AC, 0x00) ; Write_Byte_DDS(0x01AD, 0x00) ; Write_Byte_DDS(0x0200, 0x01) ; // HSTL output doubler disabled Write_Byte_DDS(0x0201, 0x00) ; Write_Byte_DDS(0x040B, ASF ) ; // DAC full-scale current, Bits[7:0] Write_Byte_DDS(0x040C, 0x00) ; // DAC full-scale current, Bits[9:8] Write_Byte_DDS(0x040E, 0x10) ; Write_Byte_DDS(0x0500, 0x00) ; Write_Byte_DDS(0x0501, 0x00) ; Write_Byte_DDS(0x0502, 0x00) ; Write_Byte_DDS(0x0503, 0x00) ; Write_Byte_DDS(0x0504, 0x00) ; Write_Byte_DDS(0x0505, 0x00) ; Write_Byte_DDS(0x0506, 0x00) ; Write_Byte_DDS(0x0507, 0x00) ; Write_Byte_DDS(0x0508, 0x00) ; Write_Byte_DDS(0x0509, 0x00) ; IO_Update_DDS() ; } void IO_Update_DDS() { digitalWrite(IO_UPDATE, HIGH) ; delay(1) ; digitalWrite(IO_UPDATE, LOW) ; } void Serial_OUT(byte payload) { if(payload < 0x10) Serial.print("0") ; Serial.print(payload, HEX) ; } void Freq_Update_DDS() { // FREQ = FTW * 1 GHz / 2^48 unsigned long FTW ; // 0x028F5C28F5C3 = 10 MHz unsigned long FAC = 4294967295 ; // 2^32-1 FTW = FREQ * 0.001 * FAC ; if(debug) Serial.print(FTW,DEC) ; if(debug) Serial.print(" => 0x") ; unsigned long AUX = 0x00 ; // MSB AUX = (FTW & 0xFF000000) >> 24 ; Write_Byte_DDS(0x01AB, AUX) ; if(debug) Serial_OUT(AUX) ; // AUX = (FTW & 0x00FF0000) >> 16 ; Write_Byte_DDS(0x01AA, AUX) ; if(debug) Serial_OUT(AUX) ; // AUX = (FTW & 0x0000FF00) >> 8 ; Write_Byte_DDS(0x01A9, AUX) ; if(debug) Serial_OUT(AUX) ; // AUX = (FTW & 0x000000FF) ; Write_Byte_DDS(0x01A8, AUX) ; if(debug) Serial_OUT(AUX) ; // Write_Byte_DDS(0x01A7, 0x23) ; if(debug) Serial_OUT(0x23) ; // LSB Write_Byte_DDS(0x01A6, 0x41) ; if(debug) Serial_OUT(0x41) ; // IO_Update_DDS() ; if(debug) Serial.println(" ") ; } // ///////////////////////////////////////////////////////////////////// // RF SOURCE ROUTING ROUTINES // ///////////////////////////////////////////////////////////////////// const int PORT_1_LED = 4 ; const int PORT_2_LED = 3 ; const int SRC_CNTRL = 5 ; // LOW = PORT1, HIGH = PORT2 int Chanel = 5 ; void Route_RF(int PORT) { if(PORT < 1) PORT = 1 ; if(PORT > 2) PORT = 2 ; if(PORT == 1) { digitalWrite(PORT_1_LED, HIGH) ; digitalWrite(PORT_2_LED, LOW) ; digitalWrite(SRC_CNTRL, LOW) ; } if(PORT == 2) { digitalWrite(PORT_1_LED, LOW) ; digitalWrite(PORT_2_LED, HIGH) ; digitalWrite(SRC_CNTRL, HIGH) ; } if(debug) Serial.print("Port : ") ; if(debug) Serial.println(PORT,DEC) ; } // ///////////////////////////////////////////////////////////////////// // DAC ROUTINES // ///////////////////////////////////////////////////////////////////// float LVLA = -19.0 ; // FORWARD PORT 1 float LVLB = -29.0 ; // REFLECTED PORT 1 float LVLC = -39.0 ; // REFLECTED PORT 2 float LVLD = -49.0 ; // FORWARD PORT 2 const int LVLAPin = A3 ; const int LVLBPin = A2 ; const int LVLCPin = A1 ; const int LVLDPin = A0 ; const float SLOPE = 39.847 ; const float INTERCEPT = -85.541 ; // COUPLER COMPENSATION const float CPL_A = 10.0 ; const float CPL_B = 10.0 ; const float CPL_C = 10.0 ; const float CPL_D = 10.0 ; // ///////////////////////////////////////////////////////////////////// // OTHER ROUTINES // ///////////////////////////////////////////////////////////////////// void GREETINGS() { Serial.println("TOBIMOD 9.1 BY CHANGPUAK.CH") ; Serial.println("26.03.2023, (C) ETH QUANTUMOPTICS") ; LVLA = (float)(map(analogRead(LVLAPin),0,1023,0,2500)) / 1000.0 ; LVLA = LVLA * SLOPE + INTERCEPT + CPL_A ; LVLB = (float)(map(analogRead(LVLBPin),0,1023,0,2500)) / 1000.0 ; LVLB = LVLB * SLOPE + INTERCEPT + CPL_B ; LVLC = (float)(map(analogRead(LVLCPin),0,1023,0,2500)) / 1000.0 ; LVLC = LVLC * SLOPE + INTERCEPT + CPL_C ; LVLD = (float)(map(analogRead(LVLDPin),0,1023,0,2500)) / 1000.0 ; LVLD = LVLD * SLOPE + INTERCEPT + CPL_D ; Serial.print("FREQ : ") ; Serial.print(FREQ, 3) ; Serial.println(" MHz") ; Serial.print("LEVEL A : ") ; Serial.print(LVLA, 2) ; Serial.println(" dBm") ; Serial.print("LEVEL B : ") ; Serial.print(LVLB, 2) ; Serial.println(" dBm") ; Serial.print("LEVEL C : ") ; Serial.print(LVLC, 2) ; Serial.println(" dBm") ; Serial.print("LEVEL D : ") ; Serial.print(LVLD, 2) ; Serial.println(" dBm") ; } // ///////////////////////////////////////////////////////////////////// // S E T U P // ///////////////////////////////////////////////////////////////////// void setup() { Serial.begin(115200) ; // Wire.begin() ; // DDS pinMode(SCLK, OUTPUT) ; pinMode(SDIO, OUTPUT) ; pinMode(SDO, INPUT) ; pinMode(CSB, OUTPUT) ; pinMode(IO_UPDATE, OUTPUT) ; pinMode(SRC_CNTRL, OUTPUT) ; Init_DDS() ; // ADC pinMode(LVLAPin, INPUT) ; pinMode(LVLBPin, INPUT) ; pinMode(LVLCPin, INPUT) ; pinMode(LVLDPin, INPUT) ; analogReference(EXTERNAL) ; // 2.5 V // RF ROUTING INDICATOR LED pinMode(PORT_1_LED, OUTPUT) ; pinMode(PORT_2_LED, OUTPUT) ; digitalWrite(PORT_1_LED, HIGH) ; digitalWrite(PORT_2_LED, HIGH) ; delay(999) ; Route_RF(1) ; GREETINGS() ; // DDS : AD 9912 Init_DDS() ; Freq_Update_DDS() ; delay(999) ; Freq_Update_DDS() ; } // ///////////////////////////////////////////////////////////////////// // M A I N // ///////////////////////////////////////////////////////////////////// void loop() { while (Serial.available() > 0) // ////////////////////////////////// { int tmp; char st[20]; char rx = Serial.read(); // read a single character buffer += rx; //add character to the string buffer if ((rx == '\n') || (rx == '\r')) { buffer.toCharArray(tempbuf, 40); if (buffer.startsWith("SETF:")) { sscanf(tempbuf,"SETF:%s",&st); // extract frequency as float FREQ = strtod(st,NULL); if(FREQ < MINFREQ) FREQ = MINFREQ ; if(FREQ > MAXFREQ) FREQ = MAXFREQ ; Freq_Update_DDS() ; } else if (buffer.startsWith("SETC:")) { sscanf(tempbuf,"SETC:%s",&st); // extract channel as float Chanel = strtod(st,NULL); Route_RF(Chanel) ; } else if (buffer.startsWith("GETA?")) { LVLA = (float)(map(analogRead(LVLAPin),0,1023,0,2500)) / 1000.0 ; LVLA = LVLA * SLOPE + INTERCEPT + CPL_A ; Serial.println(LVLA, 3) ; } else if (buffer.startsWith("GETB?")) { LVLB = (float)(map(analogRead(LVLBPin),0,1023,0,2500)) / 1000.0 ; LVLB = LVLB * SLOPE + INTERCEPT + CPL_B ; Serial.println(LVLB, 3) ; } else if (buffer.startsWith("GETC?")) { LVLC = (float)(map(analogRead(LVLCPin),0,1023,0,2500)) / 1000.0 ; LVLC = LVLC * SLOPE + INTERCEPT + CPL_C ; Serial.println(LVLC, 3) ; } else if (buffer.startsWith("GETD?")) { LVLD = (float)(map(analogRead(LVLDPin),0,1023,0,2500)) / 1000.0 ; LVLD = LVLD * SLOPE + INTERCEPT + CPL_D ; Serial.println(LVLD, 3) ; } else if (buffer.startsWith("*IDN?")) { LVLA = (float)(map(analogRead(LVLAPin),0,1023,0,2500)) / 1000.0 ; LVLA = LVLA * SLOPE + INTERCEPT + CPL_A ; LVLB = (float)(map(analogRead(LVLBPin),0,1023,0,2500)) / 1000.0 ; LVLB = LVLB * SLOPE + INTERCEPT + CPL_B ; LVLC = (float)(map(analogRead(LVLCPin),0,1023,0,2500)) / 1000.0 ; LVLC = LVLC * SLOPE + INTERCEPT + CPL_C ; LVLD = (float)(map(analogRead(LVLDPin),0,1023,0,2500)) / 1000.0 ; LVLD = LVLD * SLOPE + INTERCEPT + CPL_D ; GREETINGS() ; } buffer = "" ; //erase buffer for next command } } delay(99) ; } // ///////////////////////////////////////////////////////////////////// // // END OF FILE // // /////////////////////////////////////////////////////////////////////