Pages: [1]   Go Down
Author Topic: Impostare serialData ,stop bit e parità per una porta creata con softwareSerial  (Read 941 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Utlizzando questo comando in uno  sketch
Code:
UCSR0C = ( UCSR0C & ~_BV(UPM00) | _BV(UPM01) );

riesco ad impostare 8-E-1 per la Serial.

Vorrei sapere, creando  una nuova porta

SoftwareSerial NewSerial =  SoftwareSerial(6, 7, true);
 come fare per impostare 8-E-1 , in quanto in questo caso
Code:
UCSR0C = ( UCSR0C & ~_BV(UPM00) | _BV(UPM01) );

sembra non funzionare.

Grazie
Logged

rome
Offline Offline
Sr. Member
****
Karma: 17
Posts: 487
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non vorrei dire una castroneria, ma UCSR0C è uno dei registri e dovrebbe funzionare solo con la seriale builtin e non con quelle software.
Logged

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

please,spiega a tutti cosa intendi con 8-e-1..poi,essendo software,non puoi usare i maneggiamenti sui registri dell'hardware serial..
se volevi modificare i bit di parità o altro,ti cosiglierei di guardare un attimo il metodo recv della libreria(io ho la softwareSerial dell'arduino 1,ma dovrebbe essere equivalente)
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 361
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Qui di seguito il file SoftwareSerial.cpp modificata per 8-E-1.

La modifica riguarda solo la trasmissione, ma se ti serve puoi fare la stessa modifica anche per la ricezione.

Code:
/*
  SoftwareSerial.cpp - Software serial library
  Copyright (c) 2006 David A. Mellis.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/******************************************************************************
 * Includes
 ******************************************************************************/

#include "WConstants.h"
#include "SoftwareSerial.h"

/******************************************************************************
 * Definitions
 ******************************************************************************/

/******************************************************************************
 * Constructors
 ******************************************************************************/

SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin)
{
  _receivePin = receivePin;
  _transmitPin = transmitPin;
  _baudRate = 0;
}

/******************************************************************************
 * User API
 ******************************************************************************/

void SoftwareSerial::begin(long speed)
{
  _baudRate = speed;
  _bitPeriod = 1000000 / _baudRate;

  digitalWrite(_transmitPin, HIGH);
  delayMicroseconds( _bitPeriod); // if we were low this establishes the end
}

int SoftwareSerial::read()
{
  int val = 0;
  int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50);
 
  // one byte of serial data (LSB first)
  // ...--\    /--\/--\/--\/--\/--\/--\/--\/--\/--...
  // \--/\--/\--/\--/\--/\--/\--/\--/\--/
  // start  0   1   2   3   4   5   6   7 stop

  while (digitalRead(_receivePin));

  // confirm that this is a real start bit, not line noise
  if (digitalRead(_receivePin) == LOW) {
    // frame start indicated by a falling edge and low start bit
    // jump to the middle of the low start bit
    delayMicroseconds(bitDelay / 2 - clockCyclesToMicroseconds(50));

    // offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
    for (int offset = 0; offset < 8; offset++) {
// jump to middle of next bit
delayMicroseconds(bitDelay);

// read bit
val |= digitalRead(_receivePin) << offset;
    }

    delayMicroseconds(_bitPeriod);
   
    return val;
  }
 
  return -1;
}

void SoftwareSerial::print(uint8_t b)
{
  if (_baudRate == 0)
    return;
   
  int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
  byte mask;
 
  bool parity = false;

  digitalWrite(_transmitPin, LOW);
  delayMicroseconds(bitDelay);

  for (mask = 0x01; mask; mask <<= 1) {
    if (b & mask){ // choose bit
      digitalWrite(_transmitPin,HIGH); // send 1
    parity = !parity;
    }
    else{
      digitalWrite(_transmitPin,LOW); // send 1
    }
    delayMicroseconds(bitDelay);
  }

 
 
 
      if (parity){ // choose bit
      digitalWrite(_transmitPin,HIGH); // send 1
    }
    else{
      digitalWrite(_transmitPin,LOW); // send 1
    }
      delayMicroseconds(bitDelay);
 
 
  digitalWrite(_transmitPin, HIGH);
  delayMicroseconds(bitDelay);
}

void SoftwareSerial::print(const char *s)
{
  while (*s)
    print(*s++);
}

void SoftwareSerial::print(char c)
{
  print((uint8_t) c);
}

void SoftwareSerial::print(int n)
{
  print((long) n);
}

void SoftwareSerial::print(unsigned int n)
{
  print((unsigned long) n);
}

void SoftwareSerial::print(long n)
{
  if (n < 0) {
    print('-');
    n = -n;
  }
  printNumber(n, 10);
}

void SoftwareSerial::print(unsigned long n)
{
  printNumber(n, 10);
}

void SoftwareSerial::print(long n, int base)
{
  if (base == 0)
    print((char) n);
  else if (base == 10)
    print(n);
  else
    printNumber(n, base);
}

void SoftwareSerial::println(void)
{
  print('\r');
  print('\n'); 
}

void SoftwareSerial::println(char c)
{
  print(c);
  println(); 
}

void SoftwareSerial::println(const char c[])
{
  print(c);
  println();
}

void SoftwareSerial::println(uint8_t b)
{
  print(b);
  println();
}

void SoftwareSerial::println(int n)
{
  print(n);
  println();
}

void SoftwareSerial::println(long n)
{
  print(n);
  println(); 
}

void SoftwareSerial::println(unsigned long n)
{
  print(n);
  println(); 
}

void SoftwareSerial::println(long n, int base)
{
  print(n, base);
  println();
}

// Private Methods /////////////////////////////////////////////////////////////

void SoftwareSerial::printNumber(unsigned long n, uint8_t base)
{
  unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  unsigned long i = 0;

  if (n == 0) {
    print('0');
    return;
  }

  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }

  for (; i > 0; i--)
    print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Qui di seguito il file SoftwareSerial.cpp modificata per 8-E-1.

La modifica riguarda solo la trasmissione, ma se ti serve puoi fare la stessa modifica anche per la ricezione.

Code:
/*
  SoftwareSerial.cpp - Software serial library
  Copyright (c) 2006 David A. Mellis.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/******************************************************************************
 * Includes
 ******************************************************************************/

#include "WConstants.h"
#include "SoftwareSerial.h"

/******************************************************************************
 * Definitions
 ******************************************************************************/

/******************************************************************************
 * Constructors
 ******************************************************************************/

SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin)
{
  _receivePin = receivePin;
  _transmitPin = transmitPin;
  _baudRate = 0;
}

/******************************************************************************
 * User API
 ******************************************************************************/

void SoftwareSerial::begin(long speed)
{
  _baudRate = speed;
  _bitPeriod = 1000000 / _baudRate;

  digitalWrite(_transmitPin, HIGH);
  delayMicroseconds( _bitPeriod); // if we were low this establishes the end
}

int SoftwareSerial::read()
{
  int val = 0;
  int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50);
 
  // one byte of serial data (LSB first)
  // ...--\    /--\/--\/--\/--\/--\/--\/--\/--\/--...
  // \--/\--/\--/\--/\--/\--/\--/\--/\--/
  // start  0   1   2   3   4   5   6   7 stop

  while (digitalRead(_receivePin));

  // confirm that this is a real start bit, not line noise
  if (digitalRead(_receivePin) == LOW) {
    // frame start indicated by a falling edge and low start bit
    // jump to the middle of the low start bit
    delayMicroseconds(bitDelay / 2 - clockCyclesToMicroseconds(50));

    // offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
    for (int offset = 0; offset < 8; offset++) {
// jump to middle of next bit
delayMicroseconds(bitDelay);

// read bit
val |= digitalRead(_receivePin) << offset;
    }

    delayMicroseconds(_bitPeriod);
   
    return val;
  }
 
  return -1;
}

void SoftwareSerial::print(uint8_t b)
{
  if (_baudRate == 0)
    return;
   
  int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
  byte mask;
 
  bool parity = false;

  digitalWrite(_transmitPin, LOW);
  delayMicroseconds(bitDelay);

  for (mask = 0x01; mask; mask <<= 1) {
    if (b & mask){ // choose bit
      digitalWrite(_transmitPin,HIGH); // send 1
    parity = !parity;
    }
    else{
      digitalWrite(_transmitPin,LOW); // send 1
    }
    delayMicroseconds(bitDelay);
  }

 
 
 
      if (parity){ // choose bit
      digitalWrite(_transmitPin,HIGH); // send 1
    }
    else{
      digitalWrite(_transmitPin,LOW); // send 1
    }
      delayMicroseconds(bitDelay);
 
 
  digitalWrite(_transmitPin, HIGH);
  delayMicroseconds(bitDelay);
}

void SoftwareSerial::print(const char *s)
{
  while (*s)
    print(*s++);
}

void SoftwareSerial::print(char c)
{
  print((uint8_t) c);
}

void SoftwareSerial::print(int n)
{
  print((long) n);
}

void SoftwareSerial::print(unsigned int n)
{
  print((unsigned long) n);
}

void SoftwareSerial::print(long n)
{
  if (n < 0) {
    print('-');
    n = -n;
  }
  printNumber(n, 10);
}

void SoftwareSerial::print(unsigned long n)
{
  printNumber(n, 10);
}

void SoftwareSerial::print(long n, int base)
{
  if (base == 0)
    print((char) n);
  else if (base == 10)
    print(n);
  else
    printNumber(n, base);
}

void SoftwareSerial::println(void)
{
  print('\r');
  print('\n'); 
}

void SoftwareSerial::println(char c)
{
  print(c);
  println(); 
}

void SoftwareSerial::println(const char c[])
{
  print(c);
  println();
}

void SoftwareSerial::println(uint8_t b)
{
  print(b);
  println();
}

void SoftwareSerial::println(int n)
{
  print(n);
  println();
}

void SoftwareSerial::println(long n)
{
  print(n);
  println(); 
}

void SoftwareSerial::println(unsigned long n)
{
  print(n);
  println(); 
}

void SoftwareSerial::println(long n, int base)
{
  print(n, base);
  println();
}

// Private Methods /////////////////////////////////////////////////////////////

void SoftwareSerial::printNumber(unsigned long n, uint8_t base)
{
  unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  unsigned long i = 0;

  if (n == 0) {
    print('0');
    return;
  }

  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }

  for (; i > 0; i--)
    print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
}

Ti ringrazio per l'aiuto, potresti postare anche il file Header , in quanto la libreria softwareSerial che ho io è completamente diversa in , è quella di arduino 1.0.1.

Nel codice che hai postato la parte di trasmissione con 8E1 dovrebbe essere questa , ma il settaggio per 8E1 come viene realizzato?
Code:
void SoftwareSerial::print(uint8_t b)
{
  if (_baudRate == 0)
    return;
   
  int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
  byte mask;
 
  bool parity = false;

  digitalWrite(_transmitPin, LOW);
  delayMicroseconds(bitDelay);

  for (mask = 0x01; mask; mask <<= 1) {
    if (b & mask){ // choose bit
      digitalWrite(_transmitPin,HIGH); // send 1
     parity = !parity;
    }
    else{
      digitalWrite(_transmitPin,LOW); // send 1
    }
    delayMicroseconds(bitDelay);
  }

 
 
 
      if (parity){ // choose bit
      digitalWrite(_transmitPin,HIGH); // send 1
    }
    else{
      digitalWrite(_transmitPin,LOW); // send 1
    }
      delayMicroseconds(bitDelay);
 
 
  digitalWrite(_transmitPin, HIGH);
  delayMicroseconds(bitDelay);
}

Vorrei implementare l'8E1 sulla funzione write della softwareSerial piu' recente (arduino 1.01)
Code:
size_t SoftwareSerial::write(uint8_t b)
{
  if (_tx_delay == 0) {
    setWriteError();
    return 0;
  }

  uint8_t oldSREG = SREG;
  cli();  // turn off interrupts for a clean txmit

  // Write the start bit
  tx_pin_write(_inverse_logic ? HIGH : LOW);
  tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);

  // Write each of the 8 bits
  if (_inverse_logic)
  {
    for (byte mask = 0x01; mask; mask <<= 1)
    {
      if (b & mask) // choose bit
        tx_pin_write(LOW); // send 1
      else
        tx_pin_write(HIGH); // send 0
   
      tunedDelay(_tx_delay);
    }

    tx_pin_write(LOW); // restore pin to natural state
  }
  else
  {
    for (byte mask = 0x01; mask; mask <<= 1)
    {
      if (b & mask) // choose bit
        tx_pin_write(HIGH); // send 1
      else
        tx_pin_write(LOW); // send 0
   
      tunedDelay(_tx_delay);
    }

    tx_pin_write(HIGH); // restore pin to natural state
  }

  SREG = oldSREG; // turn interrupts back on
  tunedDelay(_tx_delay);
 
  return 1;
}

Spero di non chiedere troppo nel domandare un aiuto per realizzare tale modifica
Grazie
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 361
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Io uso ancora la 0.23

A me serviva trasmettere dei dati ad un PLC Siemens, che vuole la parita.

Ho chiesto aiuto ad uno che di mestiere fa il programmatore e che in pochi minuti ha fatto la modifica che vedi.
Dopo aver aperto la softwareserial.cpp ha detto "e' una stupidaggine, basta aggiungere due righe ed e' fatta"

Il mio consiglio e' di scaricarti la IDE 0.23 e confrontare la softwareserial modificata con quella originale.

Logged

Pages: [1]   Go Up
Jump to: