Outils pour utilisateurs

Outils du site


rds:monrds_coder

MONRDS CODER

NEWS

ERRATA October 16th 2011 : MONRDS1 FIXED

MONRDS1.HEX was corrupted and not working well

It is now fixed, a tested version is on the site

October 16th 2011 : AF function is ready

AF (Alternative Frequency) is only for MONRDS2 (due to memory issues).

PC software update is coming with it in order to manage alternative frequencies

it allow 6 alternative frequencies (it should be enougth for small applications)

October 23th 2011 : MONRDSTIME module is ongoing

MonRdsTime is a module with a PIC 16F628A and a RTC DS1337

It allows to give rds time on coder without a host PC, it allows to make small radios without PC

it is placed in the RS232 line between rs232 connection and the MONRDS coder

if a PC is connected, it is transparent for all incoming commands and transfer them to MONRDS

Work is in grogress…

November 6th 2011 : MJD calculation fixes

Calculation of MJD and TIme ongoing

test done, seems to be ok, just continue some tests before release it

FEATURES

  • scrolling PS capable :

(If Flash is installed, you can watch a video inside this web page.)

  • Scolling PS available even in stand alone mode
  • Effect controled by microcontroller, text scolling is syncronous with frames, so no garbage appears on the display.

2 Versions:

  • 32 chars RT and 64 chars PS with PIC16F628 ⇒ MONRDS1
  • 64 chars RT and 80 chars PS with PIC16F88 ⇒ MONRDS2

MONRDS2 includes a frame buffer to prevent framse errors during communication with computer, this is necessary due to long messages. Additionnally, MONRDS2 have a lower jitter on biphase signal, which gives a better signal.

  • Allow stand-alone mode or remote controlled

WINDOWS and LINUX control software, compiled for each OS

Linux version Windows version

Support this development

If you appreciate, fell free to support this dévelopment by clicking to button below.

There is no minimal amount, so any donation, even symbolic, is appreciated!

General considerations

What for?

My idea was to be able to listen any music of my choice at home, if possible anywhere.

As i found on Ebay a small FM transmitter, i started to connect it to my NSLU2 whit an usb audio adapter

After time, another idea went : to get on radio display the actual song title… for that i needed an RDS CODER…

Feel free to use my work, it's free !

Enjoy :-)


RDS CODING

The purpose here is not to describe RDS Coding, some other people did it before me, and very well.

My intend is to show you my personnal design (hardware and software) of my RDS CODER


What could i find on web?

I searched hard on the net, and it seems difficult to find a lot of drawings, for more some are not free at all…

here are some interesing pages:

http://www.g.laroche.free.fr/

or here:

http://pagesperso-orange.fr/tvignaud/rds/fr-rds.htm

or here:

http://renaud.cerrato.free.fr/

or here:

http://asp.bruinink.nu/rdsencoder.aspx

These persons propose their own design of RDS coders.

My intend is to propose one additionnal version with some different features….

I have a precise idea of what i need :

A box, with RS232 input (universal !) and a rds signal output… very basic.

My Rds Coder (in french MON CODEUR RDS .. MONRDS ! )

Specifications

  • Fully capable in stand alone mode
  • Allows dynamic PS like scrolling
  • RS232 ascii input
  • extandable to USB connection
  • analog rds signal output
  • able to work stand alone or connected to a computer (any)
  • customisable by EEPROM programming or by RS232 programming (including a command to store into EEPROM)
  • recalls EEPROM data's at power-up
  • PS
  • DS
  • RT
  • TA
  • TP
  • DI
  • PT
  • MS
  • PI
  • TI : time function
  • AF : Alternate Frequency function
  • EEPROM capabilities
  • SM : Store to Memory
  • RM : Recall from Memory

Minimal hardware

Maximum signal quality.

Hardware

The goal was to do the most little coder as possible. Here are the pictures:

MONRDS Boxed

Here the internal PCB

NOTE: the device includes a USB-RS232 Converter in order to have a USB Connection, and additionnally supplies the RDS CODER

MONRDS TOP MONRDS Bottom

Drawings

Here is the drawing (without USB converter)

2 Drawings due to RX pin difference between 16F648 and 16F88

You can notice that i use only 1 IC.

In order to give the purest signal, i use a transistor modulator, it uses 2 transistors, takes lees surface tanh a CD4053 or similar!

Also, all signals are generated by software, but i prefered to produce the filtered biphase signal by hardware (4th order filter) instead software.

Notice that trials with software modulation were giving good working results with my radio, but as filtering was not suffiscient, i consider that version as non acceptable, too munch harmonics are delivered.

MONRDS1 Drawing
MONRDS2 Drawing

The RDS signal is obtained by Q2 which is acting as a switch and modulates the 57kHz signal by the 1887.5 modulation signal. it acts as a symétrical modulator, due to the presence of C2 which remains charged at approx 2.5V

Q2 is acting as a simple switch, ans gives a clean signal.

The RDS signal amplitude is not perfectly constant, this is due to the lowpass filter used in the drawing. i am looking for improvement

The signal has been simulated with Open Office, the real sugnal is extremely similar to the simulation !

RDS SIGNAL SIMULATION
RDS Signal generated

Software

Commands overview

  • All commands are ASCII, no hex char accepted.
COMMAND FORMAT
field description
HEADER command header, determines wich command is send
DATA data related to the command MUST BE ASCII CHARS
<CR> mandatory terminator

for example, TA0<cr> means ASCII chars “T”, “A”, “0” followed by <cr>

This can be achieved in C++ by:

int ta=0;
 
printf("TA%d\n",ta);

THIS WILL NOT WORK :

int ta=0;
 
printf("TA%c\n",ta);

THIS TOO

int ta=0;
 
printf("TA%x\n",ta);

Command list

Port setup

Com port setup is :

9600 bauds

8 data bits

No parity

1 Stop bit

COMMANDS SUMMARY
header data comment
PS <ps name> 8 char max
DS <repeat,step> Dynamic PS parameters
RT <radiotext message> 32 char max
TA 0/1
TP 0/1
PI 0..255,0..255
PT 0..31
MS 0/1
TI 0..3,0..255,0..255,0..255,0..255 frame to calculated by host
AF 0..255, 0..255, …. frame to calculated by host
SM -none- Store to Memory RAM ⇒ EEPROM
RM -none- Recall from Memory EEPROM ⇒ RAM

Refer to RDS/RDBS specifications for more understanding of commands and parameters

DS is a specific feature to set Dymanic PS parameters:

  • repeat is the number of repetions of the same frames, a minimum of 2 is a correct choice, abd will allow a 1 second scrolling speed
  • step is the number of caracters to scroll, 1 allows a standard scrolling, 8 allows a page mode scrolling

For the TI function, the RDS coder makes no translation, data are transmitted raw, the host have to compute frame for the coder, a sample program is given below

For the AF function, the RDS coder makes no translation too.

AF parameters
Parameter <1> table
valueMeaningGroup
0No AF transmitted, using G0BG0B
224AF transmitted using but no AF, no local freqG0A
225AF transmitted using with local frequencyG0A
2261 alternative frequencyG0A
2272 alternative frequencyG0A
2283 alternative frequencyG0A
2294 alternative frequencyG0A
2305 alternative frequencyG0A
2316 alternative frequencyG0A
Parameter <2> to <8> table
valueMeaning
087,5
187,6
287,7
….
202107,7
203107,8
204107,9
205Filling code (no frequency)

DOWNLOAD

Download MONRDS Drawings

HEX FILES FOR PIC

Download MONRDS HEX file

Control software for linux and windosw.

NOTA: software will create monrds.ini file in program current folder

Download MONRDSCONTROL file
WindowsLinux

Host

Here is the monitor i use on my NSLU2

it is surveying MPD trough MPC and checks if song name is changed, if changed, it sends the new song title with a RT command

it also checks date and time, and when minute changes, sends TI command

Download MONRDS C file
 
 
#include <stdio.h>
 
#include <string.h>
 
#include <time.h>
 
#include <math.h>
 
 
 
FILE *fichier;
 
char nom[200];
 
char ancien[200];
 
char device[25];
 
char cmd[25];
 
int mjd,day,month,year,hour,min;
 
int G41,G42,G43,G44,G45;
 
int i, debug;
 
int pid;
 
time_t t;
 
struct tm *now;
 
 
 
float tms_to_jd (struct tm *tms)
 
{
 
   float month = tms->tm_mon + 1;
 
   float a = (14 - month)/12;
 
   float y = (1900+tms->tm_year)+4800-a;
 
   float m = month + 12*a - 3;
 
   float day = tms->tm_mday;
 
 
 
   float jd = day + (153*m+2)/5 + y*365 + y/4 - y/100 + y/400 - 32045;
 
 
 
   // The julian day begins at noon
 
   jd -= 0.5;
 
   return jd + (tms->tm_hour + (tms->tm_min + tms->tm_sec/60.0)/60.0)/24.0;
 
}
 
 
 
float tms_to_mjd (struct tm *tms)
 
{
 
   return tms_to_jd (tms) - 2400000.5;
 
}
 
 
 
main(int argc, char * argv[])
 
{
 
debug = 0;
 
strcpy(device,"/dev/ttyUSB0\0x00");
 
for (i=0 ;i < argc; i++)
 
    {
 
    if ( (strstr(argv[i],"-debug")) != NULL) debug = 1;		
 
    if (((strstr(argv[i],"-device")) != NULL) && ((i+1) < argc)) strcpy(device,argv[i+1]);		
 
    }
 
 
 
if (debug == 1) 
 
	{
 
	printf("device : %s\n",device);
 
	}
 
else
 
	{
 
//	strcpy(cmd,"killall ");
 
//	strcat(cmd, argv[0]);
 
//	i = system (cmd);
 
//	sleep(1);
 
	if ((pid = fork()) > 0)
 
		{
 
		sleep(1);
 
		exit(1);
 
		}
 
	}
 
 
 
min = 60;
 
	while (1)
 
	{
 
	sleep(3);
 
	system("mpc volume 100 > /var/cache/rds/mpc.txt");
 
	sleep(1);
 
	fichier = fopen("/var/cache/rds/mpc.txt", "r");
 
	if (fichier != NULL)
 
		{
 
		fgets(nom, 100, fichier);
 
		for (i=0; i< strlen(nom);i++)
 
		    {
 
		    if ((nom[i]==0x0D) || (nom[i]==0x0A)) nom[i]=0;
 
		    }
 
		fclose(fichier);
 
		if (strcmp(ancien, nom))
 
			{
 
			if (debug==1) printf("RT%s<CR>\n", nom);
 
			strcpy(ancien, nom);
 
			fichier = fopen(device, "w");
 
			if (fichier != NULL)
 
				{
 
				fprintf(fichier, "RT%s\n", nom);
 
				fclose(fichier);
 
				}
 
			}
 
		}
 
	sleep(1);
 
	t = time(NULL);
 
	now = localtime(&t);
 
	if (!(now->tm_min == min)) 
 
		{
 
		min = now->tm_min;
 
		hour = now->tm_hour;
 
 
 
		day = now->tm_mday;
 
		month = now->tm_mon;
 
		year = now->tm_year;
 
 
 
		mjd = tms_to_mjd(now);
 
 
 
		G41=((mjd >> 15) & 0x03);
 
		G42=((mjd >> 7) & 0xff);
 
		G43=((mjd << 1) & 0xff) | ((hour >> 4) & 0x01);
 
		G44=((hour << 4) & 0xf0) | ((min >> 2) & 0x0f);
 
		G45=((min << 6) & 0xc0);
 
		if (debug==1) printf("TI%d,%d,%d,%d,%d<CR>\n",G41,G42,G43,G44,G45);
 
		fichier = fopen(device, "w");
 
		if (fichier != NULL)
 
			{
 
			fprintf(fichier,"TI%d,%d,%d,%d,%d\n",G41,G42,G43,G44,G45);
 
			fclose(fichier);
 
			}
 
		}
 
	}
 
}

And the install file in order to make installation easier

Download MONRDS intallation file
 
 
#! /bin/sh
 
gcc -lm rdsmon.c -o rdsmon
 
cp rdsmon /
usr/bin/rdsmon
 
echo '#! /bin/sh' > /etc/init.d/rdsmon
 
echo '# jean jacques.goessens - crée automotiquement' >> /etc/init.d/rdsmon
 
echo '/usr/bin/rdsmon' >> /etc/init.d/rdsmon
 
chmod +x /etc/init.d/rdsmon
 
ln -s /etc/init.d/rdsmon /etc/rc1.d/S30rdsmon
 
ln -s /etc/init.d/rdsmon /etc/rc2.d/S30rdsmon
 
ln -s /etc/init.d/rdsmon /etc/rc3.d/S30rdsmon
 
ln -s /etc/init.d/rdsmon /etc/rc4.d/S30rdsmon
 
ln -s /etc/init.d/rdsmon /etc/rc5.d/S30rdsmon
 
mkdir /var/cache/rds

Contact the author

email me (french or english, some czech..) jj@goessens.dyndns.org

rds/monrds_coder.txt · Dernière modification: 2016/01/10 16:03 (modification externe)