Skip to content

CRC Error on my client when uploading #227

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>;

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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