Skip to content

CRC Error on my client when uploading #227

@estraco

Description

@estraco

Hi, I have been looking for an sdk for the MP Voxel / FlashForge Adventurer 3 for nodejs and have found nothing decent but this. I am trying to make a server so I can print anything, anywhere. The code that I have copied and modified that for some reason, won't work. It works in your app, but not mine. The files below are the only ones used. Is there any way you could help me? Thanks!

conn.ts

import net from 'net';
import { EventEmitter } from 'events';
import codes from './codes';
import { crc32 } from 'crc';
import fs from 'fs';

class Connection extends EventEmitter {
    socket: net.Socket;
    conopt = {
        host: '',
        port: 0,
    }
    sending_gcode = false;

    constructor(host: string, port: number) {
        super();
        this.socket = new net.Socket();

        this.conopt = { host, port }

        this.socket.on('data', (data) => {
            this.emit('data', data);
            const d = this.matchData(data);
            if (d.cmd === 'M105') {
                d.data = {
                    extruder: parseInt(d.data.match(/T0:([0-9]+)/)![1]),
                    bed: parseInt(d.data.match(/B:([0-9]+)/)![1]),
                }
            }
            this.emit(d.cmd, d.data);
            this.emit(codes[d.cmd], d.data);
        });

        this.socket.on('end', () => {
            this.emit('end');
        });
    }

    getTemperature() {
        this.socket.write('~M105\n');
    }

    waitFor(cmd: string) {
        return new Promise((resolve) => {
            this.socket.on('data', (data) => {
                if (data.toString().startsWith(cmd)) {
                    resolve(data);
                }
            });
        });
    }

    matchData(data: Buffer): {
        cmd: string,
        data: any
    } {
        try {
            const cmd = data.toString().match(new RegExp('CMD (?<CommandId>[MG][0-9]+) Received\.'));
            if (cmd && cmd.groups && cmd.groups.CommandId) {
                if (cmd.groups.CommandId === 'M28') this.sending_gcode = true;
                if (cmd.groups.CommandId === 'M29') this.sending_gcode = false;
            }
            if (this.sending_gcode) return { cmd: 'M28', data: data.toString() };
            return {
                cmd: cmd!.groups!.CommandId,
                data: data.toString().replace(new RegExp('CMD (?<CommandId>[MG][0-9]+) Received\.\r\n'), '')
            }
        } catch (e) {
            console.log(e);
            return {
                cmd: '',
                data: ''
            }
        }
    }

    writeCode(code: string, data: string = '') {
        this.socket.write(`~${codes[code]} ${data}\r\n`);
    }

    connect() {
        this.socket.connect(this.conopt)
    }

    printGCode(gcode: Buffer, name: string) {
        console.log(gcode.length, name);
        this.writeCode('file_start', `${gcode.length} 0:/user/${name}`);
        let count = 0;
        let offset = 0;
        while (offset < gcode.length) {
            let crc: number;
            let packet: Buffer;

            let dataSize = 0;
            if (offset + 4096 < gcode.length) {
                packet = gcode.subarray(offset, offset + 4096);

                const crcResult = crc32(packet);
                crc = crcResult;
                console.log(crcResult.toString(16));
                dataSize = 4096;
            }
            else {
                // Every packet needs to be the same size, so zero pad the last one if we need to.
                const actualLength = gcode.length - offset;
                const data = gcode.subarray(offset, actualLength + offset);

                // The CRC is for the un-padded data.
                const crcResult = crc32(data);
                crc = crcResult;
                console.log(crc.toString(16));

                packet = Buffer.alloc(4096);
                for (let i = 0; i < data.length; ++i) {
                    packet.writeUInt32LE(data[i], i);
                }

                packet.fill(0, actualLength, 4096);

                dataSize = actualLength;
            }

            // Always start each packet with four bytes
            const bufferToSend = Buffer.alloc(4096 + 16);
            bufferToSend.writeUInt16LE(0x5a, 0);
            bufferToSend.writeUInt16LE(0x5a, 1);
            bufferToSend.writeUInt16LE(0xef, 2);
            bufferToSend.writeUInt16LE(0xbf, 3);

            // Add the count of this packet, the size of the data it in (not counting padding) and the CRC.
            bufferToSend.writeUInt32BE(count, 4);
            bufferToSend.writeUInt32BE(dataSize, 8);
            bufferToSend.writeUInt32BE(crc, 12);

            // Add the data
            for (let i = 0; i < packet.length; ++i) {
                bufferToSend.writeUInt8(packet[i], i + 16);
            }

            // Send it to the printer
            fs.appendFileSync('log.txt', `Sending packet ${count} ---\n${bufferToSend}\n---\n`);
            this.socket.write(bufferToSend);

            offset += 4096;
            ++count;
        }

        this.socket.write('\n');
        this.writeCode('file_end');
    }
}

export default Connection;

codes.ts

export default {
    M601: 'start',
    M602: 'end',
    M115: 'info',
    M119: 'endstop',
    M105: 'temp',
    M27: 'status',
    M146: 'led',
    M23: 'print',
    M36: 'stop',
    M28: 'file_start',
    M29: 'file_end',
    M108: 'stop_heat',
    M651: 'fan_on',
    M652: 'fan_off',
    M114: 'position',
    M112: 'estop',
    M18: 'motor_stop',
    M17: 'motor_start',
    G92: 'set_zero',
    M610: 'change_name',
    G1: 'bed_move',
    M140: 'bed_temp',
    M104: 'extruder_temp',
    start: 'M601',
    end: 'M602',
    info: 'M115',
    endstop: 'M119',
    temp: 'M105',
    status: 'M27',
    led: 'M146',
    print: 'M23',
    stop: 'M36',
    file_start: 'M28',
    file_end: 'M29',
    stop_heat: 'M108',
    fan_on: 'M651',
    fan_off: 'M652',
    position: 'M114',
    estop: 'M112',
    motor_stop: 'M18',
    motor_start: 'M17',
    set_zero: 'G92',
    change_name: 'M610',
    bed_move: 'G1',
    bed_temp: 'M140',
    extruder_temp: 'M104',
} as Record<string, string>;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions