Go Down

Topic: String naar global char array (Read 563 times) previous topic - next topic

Naaldwijk

Dames? en heren,

De navolgende code werkten ik krijg de 'char msg' ook op telex
Code: [Select]
// Arduino RTTY Modulator
// Uses Fast PWM to produce ~8kHz 8bit audio

#include "baudot.h"
#include "pwmsine.h"

// Yeah, I really need to get rid of these globals.
// Thats next on the to-do list

char pflag = 0;
unsigned int sampleRate = 7750;
unsigned int tableSize = sizeof(sine)/sizeof(char);
unsigned int pstn = 0;
int sign = -1;
unsigned int change = 0;
unsigned int count = 0;
int sym = 0x00;

int fmark = 870;
int fspac = 700;
int baud = 45;
int bits = 8;
char lsbf = 0;

unsigned char bitPstn = 0;
int bytePstn = 0;
unsigned char tx = 1;

unsigned char charbuf = 0;
unsigned char shiftToNum = 0;
unsigned char justshifted = 0;

char msg[] = "\n\nCQ CQ CQ DE KG4SGP KG4SGP KG4SGP KN\n\n";

// compute values for tones.
unsigned int dmark = (unsigned int)((2*(long)tableSize*(long)fmark)/((long)sampleRate));
unsigned int dspac = (unsigned int)((2*(long)tableSize*(long)fspac)/((long)sampleRate));
int msgSize = sizeof(msg)/sizeof(char);
unsigned int sampPerSymb = (unsigned int)(sampleRate/baud);

void setup() {

  // stop interrupts for setup
  cli();

  // setup pins for output
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);

  // setup counter 2 for fast PWM output on pin 9 (arduino-mega)
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS21);
  TIMSK2 = _BV(TOIE2);

  // begin serial communication
  Serial.begin(9600);
  Serial.println("Started");

  // re-enable interrupts
  sei();
}

// int main
void loop() {
  if(pflag == 1){
    pflag = 0;
    Serial.println(sym);
  }
}

char calcAmp(){
  pstn += change;

  // if the position rolls off, change sign and start where you left off
  if(pstn >= tableSize) {
    pstn = pstn%tableSize;
    sign *= -1;
  }

  // return the pwm value
  return (char)(128+(sign*sine[pstn]));
}

// sets the character buffer, the current character being sent
void setCbuff(){
    int i = 0;

    // Note: the <<2)+3 is how we put the start and stop bits in
    // the baudot table is MSB on right in the form 000xxxxx
    // so when we shift two and add three it becomes 0xxxxx11 which is
    // exactly the form we need for one start bit and two stop bits when read
    // from left to right

    // try to find a match of the current character in baudot
    for(i = 0; i < (sizeof(baudot_letters)/sizeof(char)); i++){

      // look in letters
      if(msg[bytePstn] == baudot_letters[i]) {

        // if coming from numbers, send shift to letters
        if(shiftToNum == 1){
          shiftToNum = 0;
          charbuf = ((baudot[31])<<2)+3;
          justshifted = 1;
        } else {
          charbuf = ((baudot[i])<<2)+3;
        }
      }

      //look in numbers
      if(msg[bytePstn] != ' ' && msg[bytePstn] != 10
&& msg[bytePstn] == baudot_figures[i]) {
        if(shiftToNum == 0){
          shiftToNum = 1;
          charbuf = ((baudot[30])<<2)+3;
          justshifted = 1;
        } else {
          charbuf = ((baudot[i])<<2)+3;
        }
      }     
     
      // for printing the char to serial
      sym = charbuf;
      pflag = 1;
    }
}

void setSymb(char mve){

    // if its a 1 set change to dmark other wise set change to dspace
    if((charbuf&(0x01<<mve))>>mve) {
      change = dmark;
    } else {
      change = dspac;
    }
}

// This interrupt run on every sample (7128.5 times a second)
// though it should be every 7128.5 the sample rate had to be set differently
// to produce the correct baud rate and frequencies (that agree with the math)
// Why?! I'm going to figure that one out
ISR(TIMER2_OVF_vect) {
  count++;
  if (tx == 0) return;

  // if we've played enough samples for the symbol were transmitting, get next symbol
  if (count >= sampPerSymb){
    count = 0;
    bitPstn++;

    // if were at the end of the character return to the begining of a
    // character and grab the next one
    if(bitPstn > (bits-1)) {
      bitPstn = 0;
     
      // dont increment bytePstn if were transmitting a shift-to character
      if(justshifted != 1) {
        bytePstn++;
      } else {
        justshifted = 0;
      }
     
      setCbuff();
      // if were at the end of the message, return to the begining
      if (bytePstn > (msgSize-2)){
        // clear variables used here
        bitPstn = 0;
        bytePstn = 0;
        count = 0;
        return;
      }
    }

    unsigned char mve = 0;
    // endianness thing
    if (lsbf != 1) {
      // MSB first
      mve = (bits-1)-bitPstn;
    } else {
      // LSB first
      mve = bitPstn;
    }

    // get if 0 or 1 that were transmitting
    setSymb(mve);
  }

  // set PWM duty cycle
  OCR2B = calcAmp();
}


Nu heeft men niets aan een repeterende callsign, dus ik zou graag tekst vanaf een SD-card naar de telex willen versturen;

Tekst word gelezen van SD, enige waardes worden 'gereplaced'. De
Code: [Select]
char msg[] in global is vervangen door
Code: [Select]
char msg[80]

De aangepaste String wordt geconverteerd dmv
Code: [Select]
regel.toCharArray(msg, regel.length()+1);
Hierna wordt de
Code: [Select]
int msgSize = sizeof(msg)/sizeof(char); opnieuw aangeroepen, echter doet de sketch helaas niets.

Helaas, zie door de bomen het bos niet meer

sterretje

En dan nu graag de code waar je een probleem mee hebt. in een nieuwe post zodat we de oude als referentie kunnen gebruiken.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Naaldwijk

Code: [Select]
regel.toCharArray(msg,regel.length()+1);
 maakt een nieuwe charArray welke ik wel kan printen maar wordt niet opgepikt door de interrupt timer...

sterretje

En dan nu graag de code waar je een probleem mee hebt. in een nieuwe post zodat we de oude als referentie kunnen gebruiken.
Ik vermoed dat ik niet duidelijk genoeg was; mijn fout.

Het volledige programma dat de lijn regel.toCharArray(msg,regel.length()+1); bevat.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Naaldwijk

Hierbij mijn aanpassingen aan het programma, demo4,  gestart via Serialmonitor, leest het SD tekstfile dmv readLine, doet enige 'replace' en maakt er een char array van. De interrupt timer zou de charArray msg moeten oppikken maar doet dit niet....

Global/public
Code: [Select]
char msg[80];

Code: [Select]
void loop() {

  if (Serial.available() > 0) {
    startstop = Serial.parseInt();
  }//end if

  if (!startstop == 0) {
    switch (startstop) {
      case 1:
        demo1();
        break;
      case 4:
        demo4();
        break;
      default:
        // statements
        break;
    } //end switch
  } //end if

  if (pflag == 1) {
   pflag = 0;
   Serial.println(sym);
  }
}


Code: [Select]
void demo4() {
  tekst = SD.open("test.txt", FILE_READ);

  while (tekst.available()) {
    String lin = readLine();    // String readLine hieronder
    if (lin.indexOf("&")) {
      lin.toLowerCase();
      if (lin.indexOf("&de ")) {
        lin.replace("&de ", "de ");
        result = calculateDayOfYear(dag, maand, jaar);
        lin.replace("juldate" , String(result));
        lin.replace("hour", String(uur));
        lin.replace("min", String(mins));
      }
      if (lin.indexOf("month")) {
        lin.replace("&", "");
        lin.replace("day", String(dag));
        lin.replace("hour", String(uur));
        rmin = random(1, mins);
        lin.replace("rndmin", String(rmin));
        lin.replace("month", (months[maand - 1]));
        lin.replace("year", kortjaar );
      }
    }
    lin.toUpperCase();
    char msg[lin.length()+1];
    lin.toCharArray(msg, 80);
    int msgSize = sizeof(msg) / sizeof(char);
  }
  tekst.close();
  Serial.println("File closed!");
}



Code: [Select]
String readLine() {
  String received = "";
  char ch;
  while (tekst.available()) {
    ch = tekst.read();
    if (ch == '\r') {
      return String(received);
    } else {
      received += ch;
    }//end if
  }//end while
  return "";
} //end readline

sterretje

Ik moest even een extra sigaret roken om tot rust te komen. Sorry. Als iemand om een volledig programma vraagt, plaats je een volledig programma.

Nu is er weer een kans dat we dingen verkeerd zien of begrijpen.

Enfin, drie sigaretten later

Ik hoop dat ik de dingen niet verkeerd zie en dat het onderstaande de oplosing is

Van je opening post
Quote
in global is vervangen door
Code: [Select]

char msg[80]

En in demo4()
Code: [Select]
    char msg[lin.length()+1];


Die laatste msg is niet dezelfde variabele als de globale msg.

Verder, waarom readLine()? Er is een standaard functie Serial.readStringUntil(). Waarschijnlijk omdat je at niet weet; dat is ok, ik weet ook niet alles :(

Alhoewel dit deel is van de Serial class, wordt deze methode ge-erfd van de stream class. En de SD bibliotheek erft ook van de stream class en heeft dezelfde functie. Stukken makkelijker.

Code: [Select]
  while (tekst.available()) {
    String lin = tekst.readStringUntil('\r');


Tussen twee haakjes, wat doe je met de '\n' die waarschijnlijk ook deel is van het regel einde. Als die er is kun je waarschijnlijk beter lezen to '\n' en daarna het laatste karakter weggooien.

Succes
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Go Up