rpitx icon indicating copy to clipboard operation
rpitx copied to clipboard

Adjustable power?

Open pachacamac opened this issue 7 years ago • 12 comments

First of all awesome project! Thank you for making this!

Was wondering what would roughly be the TX power of a Raspberry Pi (using a Zero W myself) and if it could be adjustable by software somehow. Signal looked very strong in my tests and I would feel better knowing some specs or being able to tune TX power down somehow. :)

pachacamac avatar Nov 25 '18 17:11 pachacamac

Tx power is now set to maximum. Output power depends on frequency. Average power is around 10dbm. There is an way to set the output level, however it is very limited : only 7 levels. It could be helpfull for modulation fixed amplitude, but if for AM modulated signal, reducing power will also reducing dynamic.

F5OEO avatar Nov 25 '18 18:11 F5OEO

Thanks, that makes me feel better already ;) 10 dBm = -20 dBW = 10 mW so mostly in the range of "likely nobody cares too much if you're on free frequency bands".

So the way to set the power output level for FM signals (sure what you said for AM signals makes total sense) where would I find this in the code or documentation?

pachacamac avatar Nov 27 '18 09:11 pachacamac

Needed. I accidentally set off a pager about 190m away (trough buildings!) on 173MHz while testing (Thought my power was enough for a few meters but not more. Could have gone to jail for that if the receiver wasn't a buddy of mine ...

eopo avatar Jan 08 '19 13:01 eopo

Shutterfly, just curious, what type of antenna were you using?

dave3825us avatar Jan 08 '19 17:01 dave3825us

3-4 meters on 85 MHz for me without any antenna 😉

pyrog avatar Jan 08 '19 22:01 pyrog

I used a simple dipole, but not 𝛌/2

eopo avatar Jan 09 '19 11:01 eopo

As per https://elinux.org/RPi_Low-level_peripherals#General_Purpose_Input.2FOutput_.28GPIO.29 The output GPIO current is 16 mA= Power=3.3 * 0.707 *0.016=0.037 W =37 mW=15.5 dbm

radiojitter avatar Apr 06 '19 14:04 radiojitter

I used a simple dipole, but not 𝛌/2

How did you wire-up the dipole

Notupus avatar Sep 28 '19 21:09 Notupus

Hello How can I adjust the power ? I tried to modify the code in tune CPP (just for a CW) with this line

pad.setlevel(1); //(7 to 1 for decreasing the power)

That is the good way ? @F5OEO

Regards

Pico1991 avatar Mar 25 '24 14:03 Pico1991

@Pico1991 should work, the range is 0-7

KubaPro010 avatar Mar 25 '24 17:03 KubaPro010

Hello

I did this modifications for tune.cpp :

  • Add argument for level
  • Add argument for timeout
  • Move the level initialization after the clk declararion

I experiment the GPIO 20 too

Thanks for your feedbacks

`#include <unistd.h> #include <librpitx/librpitx.h> #include "stdio.h" #include #include <signal.h> #include <stdlib.h>

bool running=true;

#define PROGRAM_VERSION "0.2"

void print_usage(void) {

fprintf(stderr,
"\ntune -%s \n
Usage:\ntune [-f Frequency] [-l Level] [-t Tempo][-h] \n
-f float frequency carrier Hz(50 kHz to 1500 MHz),\n
-e exit immediately without killing the carrier,\n
-p set clock ppm instead of ntp adjust\n
-l Set level 0 to 7\n
-t test time (min) \n
-h help (this help).\n
\n",
PROGRAM_VERSION);

} /* end function print_usage */

static void terminate(int num) { running=false; fprintf(stderr,"Caught signal - Terminating\n");

}

int main(int argc, char* argv[]) { int a; int anyargs = 0; float SetFrequency = 434e6; dbg_setlevel(1); float drivedds=1; int tempo = 0; bool NotKill=false; bool ppmSet = false; float ppm = 0.0f; char * endptr = NULL; while(1) { //https://stacklima.com/getopt-fonction-en-c-pour-analyser-les-arguments-de-la-ligne-de-commande/ a = getopt(argc, argv, "f:l:t:ehp:");

	if(a == -1) 
	{
		if(anyargs) break;
		else a='h'; //print usage and exit
	}
	anyargs = 1;	

	switch(a)
	{
	case 'f': // Frequency
		SetFrequency = strtof(optarg, &endptr);
		if (endptr == optarg || SetFrequency <= 0.0f || SetFrequency == HUGE_VALF) {
		fprintf(stderr, "tune: not a valid frequency - '%s'", optarg);
		}
		if (SetFrequency<0.1e6) {SetFrequency=0.1e6;printf("Adapt Low Frequency\n");}
		if (SetFrequency>1000e6) {SetFrequency=1000e6;printf("Adapt High Frequency\n");}	
		//exit(1);
		
		break;	
		
	case 'l': // driver level
		drivedds=atof(optarg);
		if (drivedds<0.0) {drivedds=0.0;printf("Adapt Low Level\n");}
		if (drivedds>7.0) {drivedds=7.0;printf("Adapt High Level\n");}
		
		break;
	case 't': // Tempo test
		tempo=atoi(optarg);
		if (tempo<0) {tempo=0;printf("Tempo NEGATF\n");exit(1);}			
		break;
		
	case 'e': //End immediately
		NotKill=true;
		break;
	case 'p': //ppm
	      ppm = strtof(optarg, &endptr);
	      if (endptr == optarg || ppm <= 0.0f || ppm == HUGE_VALF) {
		fprintf(stderr, "tune: not a valid ppm - '%s'", optarg);
		exit(1);
		}
		ppmSet = true;
		break;	
	case 'h': // help
		print_usage();
		exit(1);
		break;
	case -1:
    	break;
	case '?':
		if (isprint(optopt) )
		{
			fprintf(stderr, "tune: unknown option `-%c'.\n", optopt);
		}
		else
		{
			fprintf(stderr, "tune: unknown option character `\\x%x'.\n", optopt);
		}
		print_usage();

		exit(1);
		break;			
	default:
		print_usage();
		exit(1);
		break;
	}/* end switch a */
}/* end while getopt() */



 for (int i = 0; i < 64; i++) {
    struct sigaction sa;

    std::memset(&sa, 0, sizeof(sa));
    sa.sa_handler = terminate;
    sigaction(i, &sa, NULL);
}

	generalgpio gengpio;
	gengpio.setpulloff(4);
	padgpio pad;
	
	//pad.setlevel(drivedds);
	
	clkgpio *clk=new clkgpio;
	
	pad.setlevel(drivedds);
	
	
	clk->SetAdvancedPllMode(true);
	if(ppmSet)	//ppm is set else use ntp
		clk->Setppm(ppm);
	clk->SetCenterFrequency(SetFrequency,10);
	clk->SetFrequency(000);
	//clk->enableclk(4);
	
	//clk->enableclk(6);//CLK2 : experimental
	clk->enableclk(20);//CLK1 duplicate on GPIO20 for more power ?
	if(!NotKill)
	{
		if(tempo != 0){
			int j = 0;
			while(j < tempo*60 and running)
			{
				sleep(1);
				j += 1;
				fprintf(stderr, "tune remains - '%i'\n", (tempo*60-j));
				
			}
		}
		else {
			while(running){
			sleep(1);
			}
		}
		clk->disableclk(4);
		clk->disableclk(6);
		clk->disableclk(20);
		delete(clk);
	}
	else
	{
		//Ugly method : not destroying clk object will not call destructor thus leaving clk running 
	}

}

`

Pico1991 avatar Mar 26 '24 07:03 Pico1991

Hi, I don’t understand, the actual code doesn’t deal with txpower argument? Your patch is needed? Have you make a pull request?

cedricpah avatar Apr 18 '24 20:04 cedricpah