How to send DiSEqC commands ?

Hey folks :slight_smile: ,

first I am sorry I just attached the code, but did not use code tags.
I have changed and updated the code now.

I am working on a project, controlling a heliostat via a DiSEqC motor (Moteck Sg-2100A) and Arduino UNO.

Curcuitry is working fine, but the thing is my code.

I have to modulate a 22kHz carrier signal to:

  • logical 0: on 1ms, off 0.5ms
  • logical 1: on 0.5ms, off 1ms

The 22kHz carrier signal is generated fine, but my problems start with the bit modulation.

For generating the carrier signal, I am using timer2. For bit modulation now I am trying to change the compare register OCR2A after 22 cycles have passed. For this I increment the cnt variable.

My problem now is, that I don't know how to manage the calls of ISR() and f_on(). After the first ISR() call, I want f_on() to continue with the steps after the ISR() has been called 21 more times (overall 22 times). Then f_on() calls f_off(). f_off() then changes OCR2A to the corresponding value for 1ms or 0.5ms signal off so it interrupts only once.
After that bitCheck() is called and the whole thing starts again.

But my motor does not react to any command. The LED just blinks orange (from green before) for about 200ms (it's hard to recognize).

//#defineĀ  TIMER2STARTĀ  OCR2A |= B00101100Ā  //B01111111
//#defineĀ  TIMER2STOPĀ  OCR2A = 0

#define TIMER2START TCCR2A |= (1 << COM2A0)
#define TIMER2STOP TCCR2A &= (0 << COM2A0)

#define TIMER2PRESC_8 TCCR2B = B00001010; mode = 0;
#define TIMER2PRESC_32 TCCR2B = B00001011; mode = 1;

#define MODULATION_HI mode = 1
#define MODULATION_LO mode = 0
#define MODULATION_ISHI mode == 1
#define MODULATION_ISLO mode == 0


#define TIMER2OUTPUTsetĀ  DDRB |= (1 << DDB3)// | TIMSK2 |= (1 << OCIE2A)Ā  // set PB3 as OUTPUT (Ard: PIN11)
#define TIMER2OUTPUTresetĀ  DDRB &= (0 << DDB3) | TIMSK2 &= (0 << OCIE2A)

#define TIMER2OUTPUTtoggleĀ  DDRB ^= (1 << DDB3)Ā  // toggle PB3
#define TIMER2OUTPUTpinsetĀ  PINB |= (1 << PINB3)
#define TIMER2OUTPUTpinresetĀ  PINB &= (0 << PINB3)

byte mode = 0;

byte bitValue = 0;
boolean ACK1 = false;
boolean ACK2 = false;
byte j = 0;
unsigned int test = 0;

volatile unsigned int cnt = 0;
volatile int compare = 0;

String goWest = "101000011001100010011010011010000000";
//String goWest = "000000000000000001111111111111111111";

void timer2Init()
{
 TCCR2A = _BV(WGM21) | _BV(WGM20);
 //TIMER2PRESC_8;
 TCCR2B = _BV(WGM22) | _BV(CS21); //prescaler = 8
// OCR2A = B00101100;Ā  //44 : 22.22kHzĀ  //B11000111; // 199, so timer2 counts from 0 to 199 (200 cycles at 16 MHz)
 TIMSK2 |= (1 << OCIE2A);
}

ISR(TIMER2_COMPA_vect){
// cli();
 if (MODULATION_ISHI){
 cnt++;
 if (cnt == 21){
 TIMER2STOP;
 fOff(bitValue);
 }
 else
 Serial.println("while1");
 }
 else if (MODULATION_ISLO){
 txACK = true;
 }
// sei();
}

void fOn(byte bitValue){
 switch (bitValue){
 case 0:
 {
 OCR2A = B00101100; //22kHz
 TIMER2PRESC_8;
 MODULATION_HI;
 TIMER2START;
 /*while (cnt < 21)
 while (1);*/
 /*do{
 if (cnt == 21){
 TIMER2STOP;
 fOff(bitValue);
 }
 else
 Serial.println("while1");
 }
 while (cnt < 21);*/
 cnt = 0;
 }
 break;
 case 1:
 {
 OCR2A = B00101100;
 TIMER2PRESC_8;
 MODULATION_HI;
 TIMER2START;
 /*do{
 if (cnt == 11){
 TIMER2STOP;
 fOff(bitValue);
 }
 else
 Serial.println("while2");
 }
 while (cnt < 12);*/
 cnt = 0;
 }
 break;
 }
}

boolean fOff(int bitValue){
 switch (bitValue){
 case 0:
 {
 OCR2A = B01111100; //124: 2kHz: ISR() after 0.5ms
 TIMER2PRESC_32;
 MODULATION_LO;
 TIMER2START;
 if (txACK == true){
 TIMER2STOP;
 }
 txACK = false;
 bitCheck();
 }
 break;
 case 1:
 {
 OCR2A = B11111001; //249: 1kHz: ISR() after 1ms
 TIMER2PRESC_32;
 MODULATION_LO;
 TIMER2START;
 if (txACK == true){
 TIMER2STOP;
 }
 txACK = false;
 bitCheck();
 }
 break;
 }
 return(txACK);
}



byte bitCheck(){
 for (j = 0; j < 36; j++){
 if (goWest[j] == '1'){
 bitValue = 1;
 fOn(bitValue);
 }
 else if (goWest[j] == '0'){
 bitValue = 0;
 fOn(bitValue);
 }
 else
 Serial.println("Error in command string!");
 }
 return(bitValue);
}

void setup()
{
 TIMER2OUTPUTset;
 Serial.begin(57600);
 timer2Init();
 Serial.println(goWest);
 bitCheck();
// TIMER2START;
}

void loop()
{
 test++;
}

It would be awesome if somebody could help with that! :grin:

Thanks in advance
cyrusxx

No one has any idea?

You need to make it easier for people to help you.

Post your code using code tags

so that it will appear in a window, like this

The way you have posted your code, means that in order for us to see it, we have to:

  • download the code
  • save it in a folder named 'Code_002'
  • open the Arduino IDE
  • view the code in the IDE
  • delete the unwanted code when finished

I can't be bothered to do all that just to see your code. I'm sure other perople may have the same attitude.

Thanks for the tip JohnLincoln. Probably you're right :wink:

I have updated my first post now.

Still know one has any idea?

This is a new version, but I couldn't test it yet:

#define	TIMER2START	TCCR2A |= (1 << COM2A0)
#define TIMER2STOP	TCCR2A &= (0 << COM2A0); TIMSK2 &= (0 << OCIE2A);

#define TIMER2PRESC_8	TCCR2B = B00001010;	mode = 0;
#define TIMER2PRESC_32	TCCR2B = B00001011;	mode = 1;

#define MODULATION_HI	mode = 1
#define MODULATION_LO	mode = 0
#define MODULATION_ISHI	mode == 1
#define	MODULATION_ISLO	mode == 0


#define	TIMER2OUTPUTsetĀ  DDRB |= (1 << DDB3)// | TIMSK2 |= (1 << OCIE2A)Ā  // set PB3 as OUTPUT (Ard: PIN11)
#define TIMER2OUTPUTresetĀ  DDRB &= (0 << DDB3) | TIMSK2 &= (0 << OCIE2A)

#define TIMER2OUTPUTtoggleĀ  DDRB ^= (1 << DDB3)Ā  // toggle PB3
#define TIMER2OUTPUTpinsetĀ  PINB |= (1 << PINB3)
#define TIMER2OUTPUTpinresetĀ  PINB &= (0 << PINB3)
#define COMMANDLENGTH	strlen(goWest)

byte mode = 0;

byte bitValue = 0;
boolean ACKlo = false;
boolean ACKhi = false;
boolean ACKoff = false;
byte j = 0;
unsigned int test = 0;

volatile unsigned int cnt = 0;
volatile int compare = 0;

char goWest[] = "111000011001100010011010011010000000";
//String goWest = "000000000000000001111111111111111111";

void timer2Init()
{
	TCCR2A = _BV(WGM21) | _BV(WGM20);
	TCCR2B = _BV(WGM22) | _BV(CS21);	//prescaler = 8
	TIMSK2 |= (1 << OCIE2A);
}

ISR(TIMER2_COMPA_vect){
	switch (mode)
	{
	case 1:
		if (cnt == 22 && bitValue == 0){
			ACKlo;
		}
		else if (cnt == 11 && bitValue == 1){
			ACKhi;
		}
		else
			;
		cnt++;
	case 0:
		TIMER2STOP;
		break;
	default:
		Serial.println("ERROR bitValue");
	}
}

void f_On(byte bitValue){
	switch (bitValue){
	case 0:
		OCR2A = B00101100;	//22kHz
		TIMER2PRESC_8;
		MODULATION_HI;
		TIMER2START;
		if (ACKlo){
			cli();
			TIMER2STOP;
			cnt = 0;
			f_Off(bitValue);
			sei();
		}
		break;
	case 1:
		OCR2A = B00101100;
		TIMER2PRESC_8;
		MODULATION_HI;
		TIMER2START;
		if (ACKhi){
			TIMER2STOP;
			cnt = 0;
			f_Off(bitValue);
		}
		break;
	}
}

boolean f_Off(int bitValue){
	switch (bitValue){
	case 0:
		OCR2A = B01111100;	//124: 2kHz: ISR() after 0.5ms
		TIMER2PRESC_32;
		MODULATION_LO;
		TIMER2START;
		!ACKlo;
		bitCheck();
		break;
	case 1:
		OCR2A = B11111001;	//249: 1kHz: ISR() after 1ms
		TIMER2PRESC_32;
		MODULATION_LO;
		TIMER2START;
		!ACKhi;
		bitCheck();
		break;
	}
	//return(ACK2);
}



//byte bitCheck(boolean ACKoff){
byte bitCheck(){
	for (j = 0; j < COMMANDLENGTH; j++){
		if (goWest[j] == '0'){
			bitValue = 0;
			f_On(bitValue);
			Serial.print("b0");
			Serial.println(j);
		}
		else if (goWest[j] == '1'){
			bitValue = 1;
			f_On(bitValue);
			Serial.print("b1");
			Serial.println(j);
		}
		else
			Serial.println("Error in command string!");
	}
	return(bitValue);
}

void setup()
{
	
	TIMER2OUTPUTset;
	Serial.begin(57600);
	timer2Init();
	Serial.println(goWest);
//	delay(500);
	bitCheck();
//	TIMER2START;
}

void loop()
{
	//test++;
}

Still no one has any idea?

Looking at enhancing my TV provider SAT receiver that has no support for Diseqc what-so-ever, I came across some great reading from Nick Gammon (how not surprising at all :slight_smile: )

Have a look it might help...

BTW, how are you injecting the signal to the Antenna cable? do you have any schematics I can look into?

BTW2. I'm not sure goWest[j] works on String objects. Better go with goWest.charAt(j)